@immich/ui 0.47.0 → 0.48.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.
@@ -3,7 +3,7 @@
3
3
  import Text from '../Text/Text.svelte';
4
4
  import { zIndex } from '../../constants.js';
5
5
  import { styleVariants } from '../../styles.js';
6
- import { MenuItemType, type ContextMenuProps, type MenuItem } from '../../types.js';
6
+ import { MenuItemType, type ContextMenuProps, type ActionItem } from '../../types.js';
7
7
  import { cleanClass, isEnabled } from '../../utilities/internal.js';
8
8
  import { DropdownMenu } from 'bits-ui';
9
9
  import { fly } from 'svelte/transition';
@@ -20,7 +20,7 @@
20
20
  ...restProps
21
21
  }: ContextMenuProps = $props();
22
22
 
23
- const isDivider = (item: MenuItem | MenuItemType): item is MenuItemType => {
23
+ const isDivider = (item: ActionItem | MenuItemType): item is MenuItemType => {
24
24
  return item === MenuItemType.Divider;
25
25
  };
26
26
 
@@ -107,7 +107,7 @@
107
107
  <DropdownMenu.Item
108
108
  textValue={item.title}
109
109
  closeOnSelect
110
- onSelect={(event) => item.onSelect?.({ event, item })}
110
+ onSelect={() => item.onAction(item)}
111
111
  class="px-1"
112
112
  >
113
113
  <div class={itemStyles({ color: item.color })}>
@@ -125,7 +125,7 @@
125
125
  <DropdownMenu.Item
126
126
  textValue={item.title}
127
127
  closeOnSelect
128
- onSelect={(event) => item.onSelect?.({ event, item })}
128
+ onSelect={() => item.onAction(item)}
129
129
  title={item.title}
130
130
  >
131
131
  <div class={cleanClass(itemStyles({ color: item.color }))}>
@@ -0,0 +1,23 @@
1
+ <script lang="ts">
2
+ import IconButton from '../IconButton/IconButton.svelte';
3
+ import { menuManager } from '../../services/menu-manager.svelte.js';
4
+ import type { ContextMenuButtonProps } from '../../types.js';
5
+ import { mdiDotsVertical } from '@mdi/js';
6
+
7
+ const {
8
+ color = 'secondary',
9
+ position = 'top-right',
10
+ icon = mdiDotsVertical,
11
+ variant = 'ghost',
12
+ shape = 'round',
13
+ items,
14
+ bottomItems,
15
+ ...rest
16
+ }: ContextMenuButtonProps = $props();
17
+
18
+ const onclick = async (event: Event) => {
19
+ await menuManager.show({ target: event.currentTarget as HTMLElement, position, items, bottomItems });
20
+ };
21
+ </script>
22
+
23
+ <IconButton {icon} {color} {shape} {variant} {...rest} {onclick} />
@@ -0,0 +1,4 @@
1
+ import type { ContextMenuButtonProps } from '../../types.js';
2
+ declare const ContextMenuButton: import("svelte").Component<ContextMenuButtonProps, {}, "">;
3
+ type ContextMenuButton = ReturnType<typeof ContextMenuButton>;
4
+ export default ContextMenuButton;
package/dist/types.d.ts CHANGED
@@ -67,6 +67,13 @@ export type CloseButtonProps = {
67
67
  class?: string;
68
68
  translations?: TranslationProps<'close'>;
69
69
  } & ButtonOrAnchor;
70
+ export type ContextMenuButtonProps = ButtonBase & {
71
+ icon?: IconLike;
72
+ position?: ContextMenuPosition;
73
+ 'aria-label': string;
74
+ items: MenuItems;
75
+ bottomItems?: Array<ActionItem | undefined>;
76
+ } & Omit<HTMLButtonAttributes, 'color' | 'size'>;
70
77
  export type IconButtonProps = ButtonBase & {
71
78
  icon: IconLike;
72
79
  flipped?: boolean;
@@ -203,23 +210,13 @@ export type ToastButton = {
203
210
  variant?: Variants;
204
211
  onClick: () => void;
205
212
  };
206
- export type MenuSelectHandler = (context: {
207
- event: Event;
208
- item: MenuItem;
209
- }) => void;
210
- export type MenuItem = {
211
- title: string;
212
- icon: IconLike;
213
- color?: Color;
214
- onSelect?: MenuSelectHandler;
215
- } & IfLike;
216
213
  export declare enum MenuItemType {
217
214
  Divider = "divider"
218
215
  }
219
- export type MenuItems = Array<MenuItem | MenuItemType | undefined>;
216
+ export type MenuItems = Array<ActionItem | MenuItemType | undefined>;
220
217
  export type MenuProps = {
221
218
  items: MenuItems;
222
- bottomItems?: (MenuItem | undefined)[];
219
+ bottomItems?: (ActionItem | undefined)[];
223
220
  size?: MenuSize;
224
221
  } & HTMLAttributes<HTMLDivElement>;
225
222
  export type ContextMenuPosition = 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
@@ -242,4 +239,14 @@ export type DatePickerProps = {
242
239
  export type IfLike = {
243
240
  $if?: () => boolean;
244
241
  };
242
+ export type ActionItemHandler<T = never> = (item: ActionItem<T>) => void | Promise<void>;
243
+ export type ActionItem<T = never> = Omit<{
244
+ title: string;
245
+ icon: IconLike;
246
+ color?: Color;
247
+ onAction: ActionItemHandler<T>;
248
+ data: T;
249
+ } & IfLike, [
250
+ T
251
+ ] extends [never] ? 'data' : ''>;
245
252
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@immich/ui",
3
- "version": "0.47.0",
3
+ "version": "0.48.0",
4
4
  "license": "GNU Affero General Public License version 3",
5
5
  "repository": {
6
6
  "type": "git",
@@ -58,7 +58,7 @@
58
58
  "@immich/svelte-markdown-preprocess": "^0.1.0"
59
59
  },
60
60
  "volta": {
61
- "node": "24.11.0"
61
+ "node": "24.11.1"
62
62
  },
63
63
  "scripts": {
64
64
  "create": "node scripts/create.js",