@immich/ui 0.57.2 → 0.58.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.
@@ -452,5 +452,6 @@ export declare const getFieldContext: () => () => {
452
452
  export declare const setTableContext: (context: () => TableContext) => () => TableContext;
453
453
  export declare const getTableContext: () => () => {
454
454
  spacing: import("../types.js").Size;
455
+ size: import("../types.js").Size;
455
456
  striped: boolean;
456
457
  };
@@ -14,7 +14,7 @@ export const setTableContext = (context) => setContext(tableKey, context);
14
14
  export const getTableContext = () => {
15
15
  return () => {
16
16
  const context = getContext(tableKey);
17
- const { spacing = 'medium', striped = false } = context?.() || {};
18
- return { spacing, striped };
17
+ const { spacing = 'medium', size = 'medium', striped = false } = context?.() || {};
18
+ return { spacing, size, striped };
19
19
  };
20
20
  };
@@ -11,7 +11,7 @@
11
11
  const { color = 'primary', size = 'medium', name }: Props = $props();
12
12
 
13
13
  const styles = tv({
14
- base: 'flex h-full w-full items-center justify-center font-medium text-white select-none',
14
+ base: 'flex items-center justify-center font-medium text-white select-none',
15
15
  variants: {
16
16
  size: {
17
17
  tiny: 'h-5 w-5 text-xs',
@@ -36,7 +36,7 @@
36
36
  });
37
37
 
38
38
  const wrapper = tv({
39
- base: 'overflow-hidden rounded-full shadow-md',
39
+ base: 'block w-full overflow-hidden rounded-full shadow-md',
40
40
  });
41
41
 
42
42
  const getInitials = (name: string) => {
@@ -2,7 +2,7 @@
2
2
  import Button from '../../internal/Button.svelte';
3
3
  import type { ButtonProps } from '../../types.js';
4
4
 
5
- let { ref = $bindable(null), ...props }: ButtonProps = $props();
5
+ let { ref = $bindable(null), color = 'primary', ...props }: ButtonProps = $props();
6
6
  </script>
7
7
 
8
- <Button bind:ref {...props} />
8
+ <Button bind:ref {color} {...props} />
@@ -3,11 +3,19 @@
3
3
  import Button from '../../internal/Button.svelte';
4
4
  import type { IconButtonProps } from '../../types.js';
5
5
 
6
- const { icon, flipped, flopped, title, 'aria-label': ariaLabel, ...buttonProps }: IconButtonProps = $props();
6
+ const {
7
+ icon,
8
+ flipped,
9
+ flopped,
10
+ title,
11
+ 'aria-label': ariaLabel,
12
+ color = 'primary',
13
+ ...buttonProps
14
+ }: IconButtonProps = $props();
7
15
 
8
16
  const buttonTitle = $derived(title ?? ariaLabel);
9
17
  </script>
10
18
 
11
- <Button icon {...buttonProps} title={buttonTitle} aria-label={ariaLabel}>
19
+ <Button icon {color} {...buttonProps} title={buttonTitle} aria-label={ariaLabel}>
12
20
  <Icon {icon} {flipped} {flopped} size="60%" aria-hidden />
13
21
  </Button>
@@ -0,0 +1,51 @@
1
+ <script lang="ts">
2
+ import Icon from '../Icon/Icon.svelte';
3
+ import HStack from '../Stack/HStack.svelte';
4
+ import Button from '../../internal/Button.svelte';
5
+ import type { ButtonProps, IconLike } from '../../types.js';
6
+ import { cleanClass, isIconLike } from '../../utilities/internal.js';
7
+ import { mdiCheck } from '@mdi/js';
8
+ import type { Snippet } from 'svelte';
9
+ import { tv } from 'tailwind-variants';
10
+
11
+ let {
12
+ ref = $bindable(null),
13
+ selected = false,
14
+ class: className,
15
+ selectedIcon = mdiCheck,
16
+ children,
17
+ ...props
18
+ }: ButtonProps & {
19
+ color?: never;
20
+ selected?: boolean;
21
+ disabled?: boolean;
22
+ selectedIcon?: IconLike | Snippet | false;
23
+ } = $props();
24
+
25
+ const styles = tv({
26
+ base: 'hover:bg-light-200 dark:hover:bg-light-300 text-dark',
27
+ variants: {
28
+ selected: {
29
+ true: 'bg-light-200 dark:bg-light-300',
30
+ false: '',
31
+ },
32
+ },
33
+ });
34
+ </script>
35
+
36
+ <Button bind:ref fullWidth class={cleanClass(styles({ selected }), className)} {...props}>
37
+ {#if selectedIcon}
38
+ <HStack fullWidth class="justify-between">
39
+ {@render children?.()}
40
+ {#if selected}
41
+ {#if isIconLike(selectedIcon)}
42
+ <Icon icon={selectedIcon} />
43
+ {:else}
44
+ {@render selectedIcon()}
45
+ {/if}
46
+ {/if}
47
+ </HStack>
48
+ {:else}
49
+ {@render children?.()}
50
+ {/if}
51
+ </Button>
@@ -0,0 +1,11 @@
1
+ import type { ButtonProps, IconLike } from '../../types.js';
2
+ import type { Snippet } from 'svelte';
3
+ type $$ComponentProps = ButtonProps & {
4
+ color?: never;
5
+ selected?: boolean;
6
+ disabled?: boolean;
7
+ selectedIcon?: IconLike | Snippet | false;
8
+ };
9
+ declare const ListButton: import("svelte").Component<$$ComponentProps, {}, "ref">;
10
+ type ListButton = ReturnType<typeof ListButton>;
11
+ export default ListButton;
@@ -11,13 +11,26 @@
11
11
  type Props = {
12
12
  class?: string;
13
13
  ref?: HTMLTableElement | null;
14
+ rounded?: boolean;
15
+ shape?: 'semi-round' | 'rectangle';
16
+ border?: boolean;
14
17
  children?: Snippet;
15
18
  } & TableContext &
16
19
  Omit<HTMLAttributes<HTMLTableElement>, 'color' | 'size'>;
17
20
 
18
- let { ref = $bindable(null), class: className, striped = false, spacing, children, ...restProps }: Props = $props();
21
+ let {
22
+ ref = $bindable(null),
23
+ class: className,
24
+ size,
25
+ striped = false,
26
+ spacing,
27
+ border = true,
28
+ shape = 'semi-round',
29
+ children,
30
+ ...restProps
31
+ }: Props = $props();
19
32
 
20
- setTableContext(() => ({ spacing, striped }));
33
+ setTableContext(() => ({ spacing, striped, size }));
21
34
 
22
35
  const { getChildren: getChildSnippet } = withChildrenSnippets(ChildKey.Table);
23
36
  const headerChild = $derived(getChildSnippet(ChildKey.TableHeader));
@@ -28,13 +41,31 @@
28
41
  base: 'bg-dark-900 flex w-full place-items-center',
29
42
  variants: {
30
43
  spacing: styleVariants.tableSpacing,
44
+ shape: {
45
+ 'semi-round': 'rounded-md',
46
+ rectangle: 'rounded-none',
47
+ },
48
+ },
49
+ });
50
+
51
+ const commonStyles = tv({
52
+ base: '',
53
+ variants: {
54
+ shape: {
55
+ 'semi-round': 'rounded-md',
56
+ rectangle: 'rounded-none',
57
+ },
58
+ border: {
59
+ true: 'border',
60
+ false: '',
61
+ },
31
62
  },
32
63
  });
33
64
  </script>
34
65
 
35
66
  <table bind:this={ref} class={cleanClass('w-full text-center', className)} {...restProps}>
36
67
  {#if headerChild}
37
- <thead class="text-primary mb-4 flex w-full overflow-hidden rounded-md border">
68
+ <thead class={cleanClass('text-primary mb-4 flex w-full overflow-hidden', commonStyles({ shape, border }))}>
38
69
  <tr class={headerRowStyles({ spacing })}>
39
70
  {@render headerChild?.snippet()}
40
71
  </tr>
@@ -42,7 +73,7 @@
42
73
  {/if}
43
74
 
44
75
  {#if bodyChild}
45
- <tbody class={cleanClass('block w-full overflow-y-auto rounded-md border', bodyChild.class)}>
76
+ <tbody class={cleanClass('block w-full overflow-y-auto', bodyChild.class, commonStyles({ shape, border }))}>
46
77
  {@render bodyChild?.snippet()}
47
78
  </tbody>
48
79
  {/if}
@@ -51,7 +82,12 @@
51
82
  </table>
52
83
 
53
84
  {#if footerChild}
54
- <div class="text-primary bg-subtle mt-4 flex h-12 w-full place-items-center rounded-md border p-4">
85
+ <div
86
+ class={cleanClass(
87
+ 'text-primary bg-subtle mt-4 flex h-12 w-full place-items-center p-4',
88
+ commonStyles({ shape, border }),
89
+ )}
90
+ >
55
91
  {@render footerChild?.snippet()}
56
92
  </div>
57
93
  {/if}
@@ -4,6 +4,9 @@ import type { HTMLAttributes } from 'svelte/elements';
4
4
  type Props = {
5
5
  class?: string;
6
6
  ref?: HTMLTableElement | null;
7
+ rounded?: boolean;
8
+ shape?: 'semi-round' | 'rectangle';
9
+ border?: boolean;
7
10
  children?: Snippet;
8
11
  } & TableContext & Omit<HTMLAttributes<HTMLTableElement>, 'color' | 'size'>;
9
12
  declare const Table: import("svelte").Component<Props, {}, "ref">;
@@ -1,23 +1,26 @@
1
1
  <script lang="ts">
2
2
  import { getTableContext } from '../../common/context.svelte.js';
3
+ import { styleVariants } from '../../styles.js';
3
4
  import { cleanClass } from '../../utilities/internal.js';
4
5
  import type { Snippet } from 'svelte';
6
+ import type { HTMLAttributes } from 'svelte/elements';
5
7
  import { tv } from 'tailwind-variants';
6
8
 
7
9
  type Props = {
8
10
  class?: string;
9
11
  children?: Snippet;
10
- };
12
+ } & HTMLAttributes<HTMLTableCellElement>;
11
13
 
12
- const { class: className, children }: Props = $props();
14
+ const { class: className, children, ...restProps }: Props = $props();
13
15
 
14
16
  const context = getTableContext();
15
17
 
16
- const { spacing } = $derived(context());
18
+ const { spacing, size } = $derived(context());
17
19
 
18
20
  const styles = tv({
19
21
  base: 'line-clamp-3 w-full overflow-hidden py-2 break-all text-ellipsis',
20
22
  variants: {
23
+ size: styleVariants.textSize,
21
24
  spacing: {
22
25
  tiny: 'px-0.5',
23
26
  small: 'px-1',
@@ -29,6 +32,6 @@
29
32
  });
30
33
  </script>
31
34
 
32
- <td class={cleanClass(styles({ spacing }), className)}>
35
+ <td class={cleanClass(styles({ spacing, size }), className)} {...restProps}>
33
36
  {@render children?.()}
34
37
  </td>
@@ -1,8 +1,9 @@
1
1
  import type { Snippet } from 'svelte';
2
+ import type { HTMLAttributes } from 'svelte/elements';
2
3
  type Props = {
3
4
  class?: string;
4
5
  children?: Snippet;
5
- };
6
+ } & HTMLAttributes<HTMLTableCellElement>;
6
7
  declare const TableCell: import("svelte").Component<Props, {}, "">;
7
8
  type TableCell = ReturnType<typeof TableCell>;
8
9
  export default TableCell;
@@ -1,15 +1,16 @@
1
1
  <script lang="ts">
2
2
  import { cleanClass } from '../../utilities/internal.js';
3
3
  import type { Snippet } from 'svelte';
4
+ import type { HTMLAttributes } from 'svelte/elements';
4
5
 
5
6
  type Props = {
6
7
  class?: string;
7
8
  children?: Snippet;
8
- };
9
+ } & HTMLAttributes<HTMLTableCellElement>;
9
10
 
10
- const { class: className, children }: Props = $props();
11
+ const { class: className, children, ...restProps }: Props = $props();
11
12
  </script>
12
13
 
13
- <th class={cleanClass('w-full px-4 py-2', className)}>
14
+ <th class={cleanClass('w-full px-4 py-2', className)} {...restProps}>
14
15
  {@render children?.()}
15
16
  </th>
@@ -1,8 +1,9 @@
1
1
  import type { Snippet } from 'svelte';
2
+ import type { HTMLAttributes } from 'svelte/elements';
2
3
  type Props = {
3
4
  class?: string;
4
5
  children?: Snippet;
5
- };
6
+ } & HTMLAttributes<HTMLTableCellElement>;
6
7
  declare const TableHeading: import("svelte").Component<Props, {}, "">;
7
8
  type TableHeading = ReturnType<typeof TableHeading>;
8
9
  export default TableHeading;
@@ -4,6 +4,7 @@
4
4
  import type { Color } from '../../types.js';
5
5
  import { cleanClass } from '../../utilities/internal.js';
6
6
  import type { Snippet } from 'svelte';
7
+ import type { HTMLAttributes } from 'svelte/elements';
7
8
  import { tv } from 'tailwind-variants';
8
9
 
9
10
  type Props = {
@@ -11,9 +12,9 @@
11
12
  children?: Snippet;
12
13
  center?: boolean;
13
14
  color?: Color;
14
- };
15
+ } & HTMLAttributes<HTMLTableRowElement>;
15
16
 
16
- const { color, class: className, children }: Props = $props();
17
+ const { color, class: className, children, ...restProps }: Props = $props();
17
18
 
18
19
  const context = getTableContext();
19
20
 
@@ -40,6 +41,6 @@
40
41
  });
41
42
  </script>
42
43
 
43
- <tr class={cleanClass(styles({ color, striped, spacing }), className)}>
44
+ <tr class={cleanClass(styles({ color, striped, spacing }), className)} {...restProps}>
44
45
  {@render children?.()}
45
46
  </tr>
@@ -1,11 +1,12 @@
1
1
  import type { Color } from '../../types.js';
2
2
  import type { Snippet } from 'svelte';
3
+ import type { HTMLAttributes } from 'svelte/elements';
3
4
  type Props = {
4
5
  class?: string;
5
6
  children?: Snippet;
6
7
  center?: boolean;
7
8
  color?: Color;
8
- };
9
+ } & HTMLAttributes<HTMLTableRowElement>;
9
10
  declare const TableRow: import("svelte").Component<Props, {}, "">;
10
11
  type TableRow = ReturnType<typeof TableRow>;
11
12
  export default TableRow;
@@ -12,11 +12,12 @@
12
12
  color?: TextColor;
13
13
  fontWeight?: FontWeight;
14
14
  variant?: TextVariant;
15
+ inline?: boolean;
15
16
  class?: string;
16
17
  children: Snippet;
17
18
  } & HTMLAttributes<HTMLElement>;
18
19
 
19
- const { color, size, fontWeight = 'normal', children, class: className, ...restProps }: Props = $props();
20
+ const { color, inline, size, fontWeight = 'normal', children, class: className, ...restProps }: Props = $props();
20
21
 
21
22
  const styles = tv({
22
23
  variants: {
@@ -25,6 +26,6 @@
25
26
  });
26
27
  </script>
27
28
 
28
- <Text tag="p" {color} {fontWeight} class={cleanClass(styles({ size }), className)} {...restProps}>
29
+ <Text tag={inline ? 'span' : 'p'} {color} {fontWeight} class={cleanClass(styles({ size }), className)} {...restProps}>
29
30
  {@render children()}
30
31
  </Text>
@@ -7,6 +7,7 @@ type Props = {
7
7
  color?: TextColor;
8
8
  fontWeight?: FontWeight;
9
9
  variant?: TextVariant;
10
+ inline?: boolean;
10
11
  class?: string;
11
12
  children: Snippet;
12
13
  } & HTMLAttributes<HTMLElement>;
package/dist/index.d.ts CHANGED
@@ -48,6 +48,7 @@ export { default as Input } from './components/Input/Input.svelte';
48
48
  export { default as Kbd } from './components/Kbd/Kbd.svelte';
49
49
  export { default as Label } from './components/Label/Label.svelte';
50
50
  export { default as Link } from './components/Link/Link.svelte';
51
+ export { default as ListButton } from './components/ListButton/ListButton.svelte';
51
52
  export { default as LoadingSpinner } from './components/LoadingSpinner/LoadingSpinner.svelte';
52
53
  export { default as Logo } from './components/Logo/Logo.svelte';
53
54
  export { Markdown } from './components/Markdown/index.js';
package/dist/index.js CHANGED
@@ -50,6 +50,7 @@ export { default as Input } from './components/Input/Input.svelte';
50
50
  export { default as Kbd } from './components/Kbd/Kbd.svelte';
51
51
  export { default as Label } from './components/Label/Label.svelte';
52
52
  export { default as Link } from './components/Link/Link.svelte';
53
+ export { default as ListButton } from './components/ListButton/ListButton.svelte';
53
54
  export { default as LoadingSpinner } from './components/LoadingSpinner/LoadingSpinner.svelte';
54
55
  export { default as Logo } from './components/Logo/Logo.svelte';
55
56
  export { Markdown } from './components/Markdown/index.js';
@@ -20,7 +20,7 @@
20
20
  type = 'button',
21
21
  href,
22
22
  variant = 'filled',
23
- color = 'primary',
23
+ color,
24
24
  shape = 'semi-round',
25
25
  size = 'medium',
26
26
  loading = false,
@@ -10,7 +10,7 @@
10
10
  /**
11
11
  * The HTML element type.
12
12
  */
13
- tag?: HeadingTag;
13
+ tag?: HeadingTag | 'span';
14
14
  fontWeight?: FontWeight;
15
15
  variant?: TextVariant;
16
16
  color?: HeadingColor;
@@ -5,7 +5,7 @@ type Props = {
5
5
  /**
6
6
  * The HTML element type.
7
7
  */
8
- tag?: HeadingTag;
8
+ tag?: HeadingTag | 'span';
9
9
  fontWeight?: FontWeight;
10
10
  variant?: TextVariant;
11
11
  color?: HeadingColor;
package/dist/styles.d.ts CHANGED
@@ -74,11 +74,15 @@ export declare const styleVariants: {
74
74
  giant: string;
75
75
  };
76
76
  fontWeight: {
77
+ thin: string;
78
+ 'extra-light': string;
77
79
  light: string;
78
80
  normal: string;
81
+ medium: string;
79
82
  'semi-bold': string;
80
83
  bold: string;
81
84
  'extra-bold': string;
85
+ black: string;
82
86
  };
83
87
  tableSpacing: {
84
88
  tiny: string;
package/dist/styles.js CHANGED
@@ -70,11 +70,15 @@ export const styleVariants = {
70
70
  giant: 'text-xl',
71
71
  },
72
72
  fontWeight: {
73
+ thin: 'font-thin',
74
+ 'extra-light': 'font-extralight',
73
75
  light: 'font-light',
74
76
  normal: 'font-normal',
77
+ medium: 'font-medium',
75
78
  'semi-bold': 'font-semibold',
76
79
  bold: 'font-bold',
77
80
  'extra-bold': 'font-extrabold',
81
+ black: 'font-black',
78
82
  },
79
83
  tableSpacing: {
80
84
  tiny: '',
package/dist/types.d.ts CHANGED
@@ -6,7 +6,7 @@ import type { HTMLAnchorAttributes, HTMLAttributes, HTMLButtonAttributes, HTMLIn
6
6
  export type Color = 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info';
7
7
  export type TextColor = Color | 'muted';
8
8
  export type TextVariant = 'italic';
9
- export type FontWeight = 'light' | 'normal' | 'semi-bold' | 'bold' | 'extra-bold';
9
+ export type FontWeight = 'thin' | 'extra-light' | 'light' | 'normal' | 'medium' | 'semi-bold' | 'bold' | 'extra-bold' | 'black';
10
10
  export type HeadingColor = TextColor;
11
11
  export type Size = 'tiny' | 'small' | 'medium' | 'large' | 'giant';
12
12
  export type ModalSize = Size | 'full';
@@ -120,6 +120,7 @@ export type FieldContext = {
120
120
  export type TableSpacing = Size;
121
121
  export type TableContext = {
122
122
  spacing?: TableSpacing;
123
+ size?: Size;
123
124
  striped?: boolean;
124
125
  };
125
126
  type BaseInputProps<T> = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@immich/ui",
3
- "version": "0.57.2",
3
+ "version": "0.58.0",
4
4
  "license": "GNU Affero General Public License version 3",
5
5
  "repository": {
6
6
  "type": "git",
@@ -37,7 +37,7 @@
37
37
  "@tailwindcss/vite": "^4.1.7",
38
38
  "@types/luxon": "^3.7.1",
39
39
  "autoprefixer": "^10.4.20",
40
- "globals": "^16.0.0",
40
+ "globals": "^17.0.0",
41
41
  "publint": "^0.3.0",
42
42
  "svelte": "^5.37.0",
43
43
  "svelte-check": "^4.0.0",