@immich/ui 0.56.0 → 0.57.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.
@@ -1,5 +1,5 @@
1
- import type { FieldContext } from '../types.js';
2
- export declare const setFieldContext: (field: FieldContext) => FieldContext;
1
+ import type { FieldContext, TableContext } from '../types.js';
2
+ export declare const setFieldContext: (context: FieldContext) => FieldContext;
3
3
  export declare const hasFieldContext: () => boolean;
4
4
  export declare const getFieldContext: () => {
5
5
  label: string | undefined;
@@ -9,4 +9,10 @@ export declare const getFieldContext: () => {
9
9
  readOnly: boolean;
10
10
  required: boolean | "indicator";
11
11
  disabled: boolean;
12
+ size: import("../types.js").Size;
13
+ };
14
+ export declare const setTableContext: (context: () => TableContext) => () => TableContext;
15
+ export declare const getTableContext: () => () => {
16
+ spacing: import("../types.js").Size;
17
+ striped: boolean;
12
18
  };
@@ -1,9 +1,18 @@
1
1
  import { withPrefix } from '../utilities/internal.js';
2
2
  import { getContext, hasContext, setContext } from 'svelte';
3
3
  const fieldKey = Symbol(withPrefix('field'));
4
- export const setFieldContext = (field) => setContext(fieldKey, field);
4
+ export const setFieldContext = (context) => setContext(fieldKey, context);
5
5
  export const hasFieldContext = () => hasContext(fieldKey);
6
6
  export const getFieldContext = () => {
7
- const { label, color = 'secondary', invalid = false, readOnly = false, required = false, disabled = false, description, } = getContext(fieldKey) || {};
8
- return { label, description, color, invalid, readOnly, required, disabled };
7
+ const { label, color = 'secondary', size = 'small', invalid = false, readOnly = false, required = false, disabled = false, description, } = getContext(fieldKey) || {};
8
+ return { label, description, color, invalid, readOnly, required, disabled, size };
9
+ };
10
+ const tableKey = Symbol(withPrefix('table'));
11
+ export const setTableContext = (context) => setContext(tableKey, context);
12
+ export const getTableContext = () => {
13
+ return () => {
14
+ const context = getContext(tableKey);
15
+ const { spacing = 'medium', striped = false } = context?.() || {};
16
+ return { spacing, striped };
17
+ };
9
18
  };
@@ -1,5 +1,5 @@
1
1
  import { ChildKey } from '../constants.js';
2
2
  import type { ChildData } from '../types.js';
3
3
  export declare const withChildrenSnippets: (key: ChildKey) => {
4
- getChildren: (key: ChildKey) => ChildData | undefined;
4
+ getChildren: <T>(key: ChildKey) => ChildData<T> | undefined;
5
5
  };
@@ -68,7 +68,7 @@
68
68
  </ModalBody>
69
69
  <ModalFooter>
70
70
  <HStack fullWidth>
71
- <Button shape="round" color={cancelColor} fullWidth onclick={onClose}>
71
+ <Button shape="round" color={cancelColor} fullWidth onclick={() => onClose()}>
72
72
  {cancelText}
73
73
  </Button>
74
74
  <Button shape="round" type="submit" tabindex={1} color={submitColor} fullWidth {disabled} form={formId}>
@@ -0,0 +1,57 @@
1
+ <script lang="ts">
2
+ import { setTableContext } from '../../common/context.svelte.js';
3
+ import { withChildrenSnippets } from '../../common/use-child.svelte.js';
4
+ import { ChildKey } from '../../constants.js';
5
+ import { styleVariants } from '../../styles.js';
6
+ import type { TableContext } from '../../types.js';
7
+ import { cleanClass } from '../../utilities/internal.js';
8
+ import { type Snippet } from 'svelte';
9
+ import type { HTMLAttributes } from 'svelte/elements';
10
+ import { tv } from 'tailwind-variants';
11
+ type Props = {
12
+ class?: string;
13
+ ref?: HTMLTableElement | null;
14
+ children?: Snippet;
15
+ } & TableContext &
16
+ Omit<HTMLAttributes<HTMLTableElement>, 'color' | 'size'>;
17
+
18
+ let { ref = $bindable(null), class: className, striped = false, spacing, children, ...restProps }: Props = $props();
19
+
20
+ setTableContext(() => ({ spacing, striped }));
21
+
22
+ const { getChildren: getChildSnippet } = withChildrenSnippets(ChildKey.Table);
23
+ const headerChild = $derived(getChildSnippet(ChildKey.TableHeader));
24
+ const bodyChild = $derived(getChildSnippet(ChildKey.TableBody));
25
+ const footerChild = $derived(getChildSnippet(ChildKey.TableFooter));
26
+
27
+ const headerRowStyles = tv({
28
+ base: 'bg-dark-900 flex w-full place-items-center',
29
+ variants: {
30
+ spacing: styleVariants.tableSpacing,
31
+ },
32
+ });
33
+ </script>
34
+
35
+ <table bind:this={ref} class={cleanClass('w-full text-center', className)} {...restProps}>
36
+ {#if headerChild}
37
+ <thead class="text-primary mb-4 flex w-full overflow-hidden rounded-md border">
38
+ <tr class={headerRowStyles({ spacing })}>
39
+ {@render headerChild?.snippet()}
40
+ </tr>
41
+ </thead>
42
+ {/if}
43
+
44
+ {#if bodyChild}
45
+ <tbody class={cleanClass('block w-full overflow-y-auto rounded-md border', bodyChild.class)}>
46
+ {@render bodyChild?.snippet()}
47
+ </tbody>
48
+ {/if}
49
+
50
+ {@render children?.()}
51
+ </table>
52
+
53
+ {#if footerChild}
54
+ <div class="text-primary bg-subtle mt-4 flex h-12 w-full place-items-center rounded-md border p-4">
55
+ {@render footerChild?.snippet()}
56
+ </div>
57
+ {/if}
@@ -0,0 +1,11 @@
1
+ import type { TableContext } from '../../types.js';
2
+ import { type Snippet } from 'svelte';
3
+ import type { HTMLAttributes } from 'svelte/elements';
4
+ type Props = {
5
+ class?: string;
6
+ ref?: HTMLTableElement | null;
7
+ children?: Snippet;
8
+ } & TableContext & Omit<HTMLAttributes<HTMLTableElement>, 'color' | 'size'>;
9
+ declare const Table: import("svelte").Component<Props, {}, "ref">;
10
+ type Table = ReturnType<typeof Table>;
11
+ export default Table;
@@ -0,0 +1,16 @@
1
+ <script lang="ts">
2
+ import { ChildKey } from '../../constants.js';
3
+ import Child from '../../internal/Child.svelte';
4
+ import type { Snippet } from 'svelte';
5
+
6
+ type Props = {
7
+ class?: string;
8
+ children: Snippet;
9
+ };
10
+
11
+ let { class: className, children }: Props = $props();
12
+ </script>
13
+
14
+ <Child for={ChildKey.Table} as={ChildKey.TableBody} class={className}>
15
+ {@render children?.()}
16
+ </Child>
@@ -0,0 +1,8 @@
1
+ import type { Snippet } from 'svelte';
2
+ type Props = {
3
+ class?: string;
4
+ children: Snippet;
5
+ };
6
+ declare const TableBody: import("svelte").Component<Props, {}, "">;
7
+ type TableBody = ReturnType<typeof TableBody>;
8
+ export default TableBody;
@@ -0,0 +1,34 @@
1
+ <script lang="ts">
2
+ import { getTableContext } from '../../common/context.svelte.js';
3
+ import { cleanClass } from '../../utilities/internal.js';
4
+ import type { Snippet } from 'svelte';
5
+ import { tv } from 'tailwind-variants';
6
+
7
+ type Props = {
8
+ class?: string;
9
+ children?: Snippet;
10
+ };
11
+
12
+ const { class: className, children }: Props = $props();
13
+
14
+ const context = getTableContext();
15
+
16
+ const { spacing } = $derived(context());
17
+
18
+ const styles = tv({
19
+ base: 'line-clamp-3 w-full overflow-hidden py-2 break-all text-ellipsis',
20
+ variants: {
21
+ spacing: {
22
+ tiny: 'px-0.5',
23
+ small: 'px-1',
24
+ medium: 'px-2',
25
+ large: 'px-2',
26
+ giant: 'px-2',
27
+ },
28
+ },
29
+ });
30
+ </script>
31
+
32
+ <td class={cleanClass(styles({ spacing }), className)}>
33
+ {@render children?.()}
34
+ </td>
@@ -0,0 +1,8 @@
1
+ import type { Snippet } from 'svelte';
2
+ type Props = {
3
+ class?: string;
4
+ children?: Snippet;
5
+ };
6
+ declare const TableCell: import("svelte").Component<Props, {}, "">;
7
+ type TableCell = ReturnType<typeof TableCell>;
8
+ export default TableCell;
@@ -0,0 +1,16 @@
1
+ <script lang="ts">
2
+ import { ChildKey } from '../../constants.js';
3
+ import Child from '../../internal/Child.svelte';
4
+ import type { Snippet } from 'svelte';
5
+
6
+ type Props = {
7
+ class?: string;
8
+ children: Snippet;
9
+ };
10
+
11
+ let { class: className, children }: Props = $props();
12
+ </script>
13
+
14
+ <Child for={ChildKey.Table} as={ChildKey.TableFooter} class={className}>
15
+ {@render children?.()}
16
+ </Child>
@@ -0,0 +1,8 @@
1
+ import type { Snippet } from 'svelte';
2
+ type Props = {
3
+ class?: string;
4
+ children: Snippet;
5
+ };
6
+ declare const TableFooter: import("svelte").Component<Props, {}, "">;
7
+ type TableFooter = ReturnType<typeof TableFooter>;
8
+ export default TableFooter;
@@ -0,0 +1,16 @@
1
+ <script lang="ts">
2
+ import { ChildKey } from '../../constants.js';
3
+ import Child from '../../internal/Child.svelte';
4
+ import type { Snippet } from 'svelte';
5
+
6
+ type Props = {
7
+ class?: string;
8
+ children: Snippet;
9
+ };
10
+
11
+ let { class: className, children }: Props = $props();
12
+ </script>
13
+
14
+ <Child for={ChildKey.Table} as={ChildKey.TableHeader} class={className}>
15
+ {@render children?.()}
16
+ </Child>
@@ -0,0 +1,8 @@
1
+ import type { Snippet } from 'svelte';
2
+ type Props = {
3
+ class?: string;
4
+ children: Snippet;
5
+ };
6
+ declare const TableHeader: import("svelte").Component<Props, {}, "">;
7
+ type TableHeader = ReturnType<typeof TableHeader>;
8
+ export default TableHeader;
@@ -0,0 +1,15 @@
1
+ <script lang="ts">
2
+ import { cleanClass } from '../../utilities/internal.js';
3
+ import type { Snippet } from 'svelte';
4
+
5
+ type Props = {
6
+ class?: string;
7
+ children?: Snippet;
8
+ };
9
+
10
+ const { class: className, children }: Props = $props();
11
+ </script>
12
+
13
+ <th class={cleanClass('w-full px-4 py-2', className)}>
14
+ {@render children?.()}
15
+ </th>
@@ -0,0 +1,8 @@
1
+ import type { Snippet } from 'svelte';
2
+ type Props = {
3
+ class?: string;
4
+ children?: Snippet;
5
+ };
6
+ declare const TableHeading: import("svelte").Component<Props, {}, "">;
7
+ type TableHeading = ReturnType<typeof TableHeading>;
8
+ export default TableHeading;
@@ -0,0 +1,45 @@
1
+ <script lang="ts">
2
+ import { getTableContext } from '../../common/context.svelte.js';
3
+ import { styleVariants } from '../../styles.js';
4
+ import type { Color } from '../../types.js';
5
+ import { cleanClass } from '../../utilities/internal.js';
6
+ import type { Snippet } from 'svelte';
7
+ import { tv } from 'tailwind-variants';
8
+
9
+ type Props = {
10
+ class?: string;
11
+ children?: Snippet;
12
+ center?: boolean;
13
+ color?: Color;
14
+ };
15
+
16
+ const { color, class: className, children }: Props = $props();
17
+
18
+ const context = getTableContext();
19
+
20
+ const { spacing, striped } = $derived(context());
21
+
22
+ const styles = tv({
23
+ base: 'flex w-full place-items-center',
24
+ variants: {
25
+ striped: {
26
+ true: 'odd:bg-dark-900 even:bg-dark-950',
27
+ false: '',
28
+ },
29
+ color: {
30
+ primary: 'bg-primary-100',
31
+ secondary: 'bg-light-200 dark:bg-light-300',
32
+ muted: 'bg-subtle text-subtle dark:bg-subtle',
33
+ info: 'bg-info-100',
34
+ warning: 'bg-warning-100',
35
+ danger: 'bg-danger-100',
36
+ success: 'bg-success-100',
37
+ },
38
+ spacing: styleVariants.tableSpacing,
39
+ },
40
+ });
41
+ </script>
42
+
43
+ <tr class={cleanClass(styles({ color, striped, spacing }), className)}>
44
+ {@render children?.()}
45
+ </tr>
@@ -0,0 +1,11 @@
1
+ import type { Color } from '../../types.js';
2
+ import type { Snippet } from 'svelte';
3
+ type Props = {
4
+ class?: string;
5
+ children?: Snippet;
6
+ center?: boolean;
7
+ color?: Color;
8
+ };
9
+ declare const TableRow: import("svelte").Component<Props, {}, "">;
10
+ type TableRow = ReturnType<typeof TableRow>;
11
+ export default TableRow;
@@ -11,7 +11,11 @@ export declare enum ChildKey {
11
11
  Modal = "modal",
12
12
  ModalHeader = "modal-header",
13
13
  ModalBody = "modal-body",
14
- ModalFooter = "modal-footer"
14
+ ModalFooter = "modal-footer",
15
+ Table = "table",
16
+ TableHeader = "table-header",
17
+ TableBody = "table-body",
18
+ TableFooter = "table-footer"
15
19
  }
16
20
  export declare const zIndex: {
17
21
  CarouselImage: string;
package/dist/constants.js CHANGED
@@ -13,6 +13,10 @@ export var ChildKey;
13
13
  ChildKey["ModalHeader"] = "modal-header";
14
14
  ChildKey["ModalBody"] = "modal-body";
15
15
  ChildKey["ModalFooter"] = "modal-footer";
16
+ ChildKey["Table"] = "table";
17
+ ChildKey["TableHeader"] = "table-header";
18
+ ChildKey["TableBody"] = "table-body";
19
+ ChildKey["TableFooter"] = "table-footer";
16
20
  })(ChildKey || (ChildKey = {}));
17
21
  export const zIndex = {
18
22
  CarouselImage: 'z-1',
package/dist/index.d.ts CHANGED
@@ -69,6 +69,13 @@ export { default as Stack } from './components/Stack/Stack.svelte';
69
69
  export { default as VStack } from './components/Stack/VStack.svelte';
70
70
  export { default as SupporterBadge } from './components/SupporterBadge/SupporterBadge.svelte';
71
71
  export { default as Switch } from './components/Switch/Switch.svelte';
72
+ export { default as Table } from './components/Table/Table.svelte';
73
+ export { default as TableBody } from './components/Table/TableBody.svelte';
74
+ export { default as TableCell } from './components/Table/TableCell.svelte';
75
+ export { default as TableFooter } from './components/Table/TableFooter.svelte';
76
+ export { default as TableHeader } from './components/Table/TableHeader.svelte';
77
+ export { default as TableHeading } from './components/Table/TableHeading.svelte';
78
+ export { default as TableRow } from './components/Table/TableRow.svelte';
72
79
  export { default as Text } from './components/Text/Text.svelte';
73
80
  export { default as Textarea } from './components/Textarea/Textarea.svelte';
74
81
  export { default as ThemeSwitcher } from './components/ThemeSwitcher/ThemeSwitcher.svelte';
package/dist/index.js CHANGED
@@ -71,6 +71,13 @@ export { default as Stack } from './components/Stack/Stack.svelte';
71
71
  export { default as VStack } from './components/Stack/VStack.svelte';
72
72
  export { default as SupporterBadge } from './components/SupporterBadge/SupporterBadge.svelte';
73
73
  export { default as Switch } from './components/Switch/Switch.svelte';
74
+ export { default as Table } from './components/Table/Table.svelte';
75
+ export { default as TableBody } from './components/Table/TableBody.svelte';
76
+ export { default as TableCell } from './components/Table/TableCell.svelte';
77
+ export { default as TableFooter } from './components/Table/TableFooter.svelte';
78
+ export { default as TableHeader } from './components/Table/TableHeader.svelte';
79
+ export { default as TableHeading } from './components/Table/TableHeading.svelte';
80
+ export { default as TableRow } from './components/Table/TableRow.svelte';
74
81
  export { default as Text } from './components/Text/Text.svelte';
75
82
  export { default as Textarea } from './components/Textarea/Textarea.svelte';
76
83
  export { default as ThemeSwitcher } from './components/ThemeSwitcher/ThemeSwitcher.svelte';
@@ -12,13 +12,14 @@
12
12
  as: ChildKey;
13
13
  class?: string;
14
14
  children: Snippet;
15
+ props?: unknown;
15
16
  };
16
17
 
17
- const { for: key, as, children, class: className }: Props = $props();
18
+ const { for: key, as, children, class: className, props = {} }: Props = $props();
18
19
 
19
20
  const context = getContext<ContextType>(withPrefix(key));
20
21
 
21
- const data = $derived({ snippet: children, class: className });
22
+ const data = $derived({ snippet: children, class: className, props });
22
23
 
23
24
  if (context) {
24
25
  context.register(as, () => data);
@@ -5,6 +5,7 @@ type Props = {
5
5
  as: ChildKey;
6
6
  class?: string;
7
7
  children: Snippet;
8
+ props?: unknown;
8
9
  };
9
10
  declare const Child: import("svelte").Component<Props, {}, "">;
10
11
  type Child = ReturnType<typeof Child>;
package/dist/styles.d.ts CHANGED
@@ -80,4 +80,11 @@ export declare const styleVariants: {
80
80
  bold: string;
81
81
  'extra-bold': string;
82
82
  };
83
+ tableSpacing: {
84
+ tiny: string;
85
+ small: string;
86
+ medium: string;
87
+ large: string;
88
+ giant: string;
89
+ };
83
90
  };
package/dist/styles.js CHANGED
@@ -12,8 +12,8 @@ export const styleVariants = {
12
12
  ...color,
13
13
  muted: 'text-gray-600 dark:text-gray-400',
14
14
  },
15
- inputCommon: 'disabled:bg-gray-300 disabled:text-dark dark:disabled:bg-gray-900 dark:disabled:text-gray-200 bg-transparent transition outline-none disabled:cursor-not-allowed ',
16
- inputContainerCommon: 'bg-gray-100 ring-1 ring-gray-200 focus-within:ring-primary dark:focus-within:ring-primary transition outline-none focus-within:ring-1 disabled:cursor-not-allowed dark:bg-gray-800 dark:ring-black',
15
+ inputCommon: 'disabled:bg-gray-300 disabled:text-dark dark:disabled:bg-gray-900 dark:disabled:text-gray-200 bg-transparent transition outline-none disabled:cursor-not-allowed',
16
+ inputContainerCommon: 'bg-gray-100 ring-1 ring-gray-200 focus-within:ring-primary dark:focus-within:ring-primary transition outline-none focus-within:ring-1 disabled:cursor-not-allowed dark:bg-gray-800 dark:ring-neutral-900',
17
17
  shape: {
18
18
  rectangle: 'rounded-none',
19
19
  'semi-round': '',
@@ -76,4 +76,11 @@ export const styleVariants = {
76
76
  bold: 'font-bold',
77
77
  'extra-bold': 'font-extrabold',
78
78
  },
79
+ tableSpacing: {
80
+ tiny: '',
81
+ small: 'py-1',
82
+ medium: 'py-2',
83
+ large: 'py-3',
84
+ giant: 'py-4',
85
+ },
79
86
  };
package/dist/types.d.ts CHANGED
@@ -90,9 +90,10 @@ type StackBaseProps = {
90
90
  fullWidth?: boolean;
91
91
  fullHeight?: boolean;
92
92
  };
93
- export type ChildData = {
93
+ export type ChildData<T = unknown> = {
94
94
  snippet: Snippet;
95
95
  class?: string;
96
+ props?: T;
96
97
  };
97
98
  export type StackProps = StackBaseProps & {
98
99
  align?: 'start' | 'center' | 'end';
@@ -116,6 +117,11 @@ export type FieldContext = {
116
117
  required?: boolean | 'indicator';
117
118
  readOnly?: boolean;
118
119
  } & LabelProps;
120
+ export type TableSpacing = Size;
121
+ export type TableContext = {
122
+ spacing?: TableSpacing;
123
+ striped?: boolean;
124
+ };
119
125
  type BaseInputProps<T> = {
120
126
  ref?: HTMLInputElement | null;
121
127
  class?: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@immich/ui",
3
- "version": "0.56.0",
3
+ "version": "0.57.0",
4
4
  "license": "GNU Affero General Public License version 3",
5
5
  "repository": {
6
6
  "type": "git",