@immich/ui 0.3.0 → 0.5.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.
Files changed (75) hide show
  1. package/dist/common/use-context.svelte.d.ts +5 -0
  2. package/dist/common/use-context.svelte.js +19 -0
  3. package/dist/components/Alert/Alert.svelte +50 -0
  4. package/dist/components/Alert/Alert.svelte.d.ts +9 -0
  5. package/dist/components/Button/Button.svelte +8 -0
  6. package/dist/components/Button/Button.svelte.d.ts +4 -0
  7. package/dist/components/Card/Card.svelte +187 -0
  8. package/dist/components/Card/Card.svelte.d.ts +11 -0
  9. package/dist/components/Card/CardBody.svelte +20 -0
  10. package/dist/components/Card/CardBody.svelte.d.ts +6 -0
  11. package/dist/components/Card/CardDescription.svelte +16 -0
  12. package/dist/components/Card/CardDescription.svelte.d.ts +6 -0
  13. package/dist/components/Card/CardFooter.svelte +15 -0
  14. package/dist/components/Card/CardFooter.svelte.d.ts +5 -0
  15. package/dist/components/Card/CardHeader.svelte +15 -0
  16. package/dist/components/Card/CardHeader.svelte.d.ts +5 -0
  17. package/dist/components/Card/CardTitle.svelte +17 -0
  18. package/dist/components/Card/CardTitle.svelte.d.ts +8 -0
  19. package/dist/components/CloseButton/CloseButton.svelte +9 -0
  20. package/dist/components/CloseButton/CloseButton.svelte.d.ts +3 -0
  21. package/dist/components/{Checkbox.svelte → Form/Checkbox.svelte} +20 -30
  22. package/dist/components/{Checkbox.svelte.d.ts → Form/Checkbox.svelte.d.ts} +1 -1
  23. package/dist/components/{Input.svelte → Form/Input.svelte} +1 -1
  24. package/dist/components/{Label.svelte → Form/Label.svelte} +1 -1
  25. package/dist/components/Heading/Heading.svelte +54 -0
  26. package/dist/components/Heading/Heading.svelte.d.ts +9 -0
  27. package/dist/components/Icon/Icon.svelte +52 -0
  28. package/dist/components/Icon/Icon.svelte.d.ts +4 -0
  29. package/dist/components/IconButton/IconButton.svelte +11 -0
  30. package/dist/components/IconButton/IconButton.svelte.d.ts +3 -0
  31. package/dist/components/Link/Link.svelte +17 -0
  32. package/dist/components/Link/Link.svelte.d.ts +8 -0
  33. package/dist/components/{Logo.svelte → Logo/Logo.svelte} +11 -10
  34. package/dist/components/{Logo.svelte.d.ts → Logo/Logo.svelte.d.ts} +1 -1
  35. package/dist/components/Stack/HStack.svelte +10 -0
  36. package/dist/components/Stack/HStack.svelte.d.ts +8 -0
  37. package/dist/components/Stack/Stack.svelte +68 -0
  38. package/dist/components/Stack/Stack.svelte.d.ts +3 -0
  39. package/dist/components/Stack/VStack.svelte +10 -0
  40. package/dist/components/Stack/VStack.svelte.d.ts +8 -0
  41. package/dist/components/SupporterBadge/SupporterBadge.svelte +94 -0
  42. package/dist/components/SupporterBadge/SupporterBadge.svelte.d.ts +9 -0
  43. package/dist/components/Text/Text.svelte +49 -0
  44. package/dist/components/Text/Text.svelte.d.ts +11 -0
  45. package/dist/constants.d.ts +6 -0
  46. package/dist/constants.js +7 -0
  47. package/dist/index.d.ts +22 -1
  48. package/dist/index.js +22 -1
  49. package/dist/{components → internal}/Button.svelte +79 -71
  50. package/dist/internal/Button.svelte.d.ts +6 -0
  51. package/dist/internal/Child.svelte +21 -0
  52. package/dist/internal/Child.svelte.d.ts +8 -0
  53. package/dist/types.d.ts +50 -0
  54. package/dist/utils.d.ts +2 -0
  55. package/dist/utils.js +1 -0
  56. package/package.json +2 -1
  57. package/dist/components/Button.svelte.d.ts +0 -15
  58. package/dist/components/Card.svelte +0 -20
  59. package/dist/components/Card.svelte.d.ts +0 -4
  60. package/dist/components/CardBody.svelte +0 -16
  61. package/dist/components/CardBody.svelte.d.ts +0 -4
  62. package/dist/components/CardDescription.svelte +0 -16
  63. package/dist/components/CardDescription.svelte.d.ts +0 -4
  64. package/dist/components/CardFooter.svelte +0 -16
  65. package/dist/components/CardFooter.svelte.d.ts +0 -4
  66. package/dist/components/CardHeader.svelte +0 -17
  67. package/dist/components/CardHeader.svelte.d.ts +0 -4
  68. package/dist/components/CardTitle.svelte +0 -25
  69. package/dist/components/CardTitle.svelte.d.ts +0 -7
  70. package/dist/components/Icon.svelte +0 -62
  71. package/dist/components/Icon.svelte.d.ts +0 -20
  72. package/dist/components/index.d.ts +0 -12
  73. package/dist/components/index.js +0 -12
  74. /package/dist/components/{Input.svelte.d.ts → Form/Input.svelte.d.ts} +0 -0
  75. /package/dist/components/{Label.svelte.d.ts → Form/Label.svelte.d.ts} +0 -0
@@ -0,0 +1,4 @@
1
+ import type { IconProps } from '../../types.js';
2
+ import type { HTMLAttributes } from 'svelte/elements';
3
+ declare const Icon: import("svelte").Component<IconProps & HTMLAttributes<EventTarget>, {}, "">;
4
+ export default Icon;
@@ -0,0 +1,11 @@
1
+ <script lang="ts">
2
+ import Button from '../../internal/Button.svelte';
3
+ import Icon from '../Icon/Icon.svelte';
4
+ import type { IconButtonProps } from '../../types.js';
5
+
6
+ const { icon, flipped, flopped, ...buttonProps }: IconButtonProps = $props();
7
+ </script>
8
+
9
+ <Button icon {...buttonProps}>
10
+ <Icon {icon} {flipped} {flopped} size="66%"></Icon>
11
+ </Button>
@@ -0,0 +1,3 @@
1
+ import type { IconButtonProps } from '../../types.js';
2
+ declare const IconButton: import("svelte").Component<IconButtonProps, {}, "">;
3
+ export default IconButton;
@@ -0,0 +1,17 @@
1
+ <script lang="ts">
2
+ import { cleanClass } from '../../utils.js';
3
+ import type { Snippet } from 'svelte';
4
+ import type { HTMLAnchorAttributes } from 'svelte/elements';
5
+
6
+ type Props = {
7
+ class?: string;
8
+ children: Snippet;
9
+ href: string;
10
+ } & HTMLAnchorAttributes;
11
+
12
+ const { href, class: className, children, ...restProps }: Props = $props();
13
+ </script>
14
+
15
+ <a {href} class={cleanClass('underline', className)} {...restProps}>
16
+ {@render children()}
17
+ </a>
@@ -0,0 +1,8 @@
1
+ import type { Snippet } from 'svelte';
2
+ import type { HTMLAnchorAttributes } from 'svelte/elements';
3
+ declare const Link: import("svelte").Component<{
4
+ class?: string;
5
+ children: Snippet;
6
+ href: string;
7
+ } & HTMLAnchorAttributes, {}, "">;
8
+ export default Link;
@@ -1,11 +1,11 @@
1
1
  <script lang="ts">
2
- import icon from '../assets/immich-logo.svg';
3
- import inlineDark from '../assets/immich-logo-inline-dark.svg';
4
- import inlineLight from '../assets/immich-logo-inline-light.svg';
5
- import stackedDark from '../assets/immich-logo-stacked-dark.svg';
6
- import stackedLight from '../assets/immich-logo-stacked-light.svg';
7
- import type { Size } from '../types.js';
8
- import { cleanClass } from '../utils.js';
2
+ import icon from '../../assets/immich-logo.svg';
3
+ import inlineDark from '../../assets/immich-logo-inline-dark.svg';
4
+ import inlineLight from '../../assets/immich-logo-inline-light.svg';
5
+ import stackedDark from '../../assets/immich-logo-stacked-dark.svg';
6
+ import stackedLight from '../../assets/immich-logo-stacked-light.svg';
7
+ import type { Size } from '../../types.js';
8
+ import { cleanClass } from '../../utils.js';
9
9
  import { tv } from 'tailwind-variants';
10
10
 
11
11
  type Props = {
@@ -15,6 +15,8 @@
15
15
  class?: string;
16
16
  };
17
17
 
18
+ const { theme = 'light', variant = 'logo', size = 'medium', class: className }: Props = $props();
19
+
18
20
  const getUrl = ({ theme, variant }: Required<Pick<Props, 'theme' | 'variant'>>): string => {
19
21
  switch (variant) {
20
22
  case 'stacked': {
@@ -31,7 +33,7 @@
31
33
  }
32
34
  };
33
35
 
34
- const logo = tv({
36
+ const styles = tv({
35
37
  variants: {
36
38
  size: {
37
39
  tiny: 'h-8',
@@ -51,8 +53,7 @@
51
53
  },
52
54
  });
53
55
 
54
- const { theme = 'light', variant = 'logo', size = 'medium', class: className }: Props = $props();
55
56
  const src = $derived(getUrl({ theme, variant }));
56
57
  </script>
57
58
 
58
- <img {src} class={cleanClass(logo({ size, variant }), className)} alt="Immich logo" />
59
+ <img {src} class={cleanClass(styles({ size, variant }), className)} alt="Immich logo" />
@@ -1,4 +1,4 @@
1
- import type { Size } from '../types.js';
1
+ import type { Size } from '../../types.js';
2
2
  declare const Logo: import("svelte").Component<{
3
3
  size?: Size | "landing";
4
4
  theme?: "dark" | "light";
@@ -0,0 +1,10 @@
1
+ <script lang="ts">
2
+ import Stack from './Stack.svelte';
3
+ import type { HStackProps } from '../../types.js';
4
+
5
+ const { class: className, children, ...props }: HStackProps = $props();
6
+ </script>
7
+
8
+ <Stack direction="row" class={className} {...props}>
9
+ {@render children()}
10
+ </Stack>
@@ -0,0 +1,8 @@
1
+ declare const HStack: import("svelte").Component<{
2
+ class?: string;
3
+ children: import("svelte").Snippet;
4
+ align?: "start" | "center" | "end";
5
+ gap?: import("../../types.js").Gap;
6
+ wrap?: boolean;
7
+ }, {}, "">;
8
+ export default HStack;
@@ -0,0 +1,68 @@
1
+ <script lang="ts">
2
+ import type { StackProps } from '../../types.js';
3
+ import { cleanClass } from '../../utils.js';
4
+ import { tv } from 'tailwind-variants';
5
+
6
+ const {
7
+ align,
8
+ direction = 'column',
9
+ wrap = false,
10
+ class: className,
11
+ gap = 2,
12
+ children,
13
+ }: StackProps = $props();
14
+
15
+ const styles = tv({
16
+ base: 'flex gap-2',
17
+ variants: {
18
+ direction: {
19
+ row: 'flex-row',
20
+ column: 'flex-col',
21
+ },
22
+ align: {
23
+ start: 'items-start',
24
+ center: 'items-center',
25
+ end: 'items-end',
26
+ },
27
+ fullWidth: {
28
+ true: 'w-full',
29
+ false: '',
30
+ },
31
+ fullHeight: {
32
+ true: 'h-full',
33
+ false: '',
34
+ },
35
+ gap: {
36
+ 0: 'gap-0',
37
+ 1: 'gap-1',
38
+ 2: 'gap-2',
39
+ 3: 'gap-3',
40
+ 4: 'gap-4',
41
+ 5: 'gap-5',
42
+ 6: 'gap-6',
43
+ 7: 'gap-7',
44
+ 8: 'gap-8',
45
+ },
46
+ wrap: {
47
+ true: 'flex-wrap',
48
+ false: '',
49
+ },
50
+ },
51
+ });
52
+ </script>
53
+
54
+ <div
55
+ class={cleanClass(
56
+ styles({
57
+ align,
58
+ direction,
59
+ gap,
60
+ wrap,
61
+ fullWidth: direction === 'row',
62
+ fullHeight: direction === 'column',
63
+ }),
64
+ className,
65
+ )}
66
+ >
67
+ {@render children()}
68
+ </div>
@@ -0,0 +1,3 @@
1
+ import type { StackProps } from '../../types.js';
2
+ declare const Stack: import("svelte").Component<StackProps, {}, "">;
3
+ export default Stack;
@@ -0,0 +1,10 @@
1
+ <script lang="ts">
2
+ import Stack from './Stack.svelte';
3
+ import type { VStackProps } from '../../types.js';
4
+
5
+ const { class: className, children, ...props }: VStackProps = $props();
6
+ </script>
7
+
8
+ <Stack direction="column" class={className} {...props}>
9
+ {@render children()}
10
+ </Stack>
@@ -0,0 +1,8 @@
1
+ declare const VStack: import("svelte").Component<{
2
+ class?: string;
3
+ children: import("svelte").Snippet;
4
+ align?: "start" | "center" | "end";
5
+ gap?: import("../../types.js").Gap;
6
+ wrap?: boolean;
7
+ }, {}, "">;
8
+ export default VStack;
@@ -0,0 +1,94 @@
1
+ <script lang="ts">
2
+ import Logo from '../Logo/Logo.svelte';
3
+ import Text from '../Text/Text.svelte';
4
+ import type { Size } from '../../types.js';
5
+ import { cleanClass } from '../../utils.js';
6
+ import type { Snippet } from 'svelte';
7
+ import { tv } from 'tailwind-variants';
8
+
9
+ type Props = {
10
+ effect?: 'hover' | 'always';
11
+ text?: string;
12
+ size?: Size;
13
+ children?: Snippet;
14
+ };
15
+
16
+ const { effect = 'hover', text = 'Supporter', size = 'medium', children }: Props = $props();
17
+
18
+ const iconSize: Record<Size, Size> = {
19
+ tiny: 'tiny',
20
+ small: 'tiny',
21
+ medium: 'small',
22
+ large: 'medium',
23
+ giant: 'medium',
24
+ };
25
+
26
+ const containerStyles = tv({
27
+ base: 'bg-secondary flex place-items-center gap-2 overflow-hidden rounded-lg transition-all',
28
+ variants: {
29
+ size: {
30
+ tiny: 'px-2 py-1',
31
+ small: 'px-2 py-1',
32
+ medium: 'px-3 py-2',
33
+ large: 'px-3 py-2',
34
+ giant: 'px-3 py-2',
35
+ },
36
+ effect: {
37
+ hover: 'border border-dark/25 supporter-effect-hover',
38
+ always: 'shadow supporter-effect',
39
+ },
40
+ },
41
+ });
42
+ </script>
43
+
44
+ <div class={cleanClass(containerStyles({ effect, size }))}>
45
+ {#if children}
46
+ {@render children()}
47
+ {:else}
48
+ <Logo size={iconSize[size]} variant="icon" />
49
+ <Text fontWeight="normal" color="secondary" {size}>{text}</Text>
50
+ {/if}
51
+ </div>
52
+
53
+ <style>
54
+ .supporter-effect,
55
+ .supporter-effect-hover:hover {
56
+ position: relative;
57
+ background-clip: padding-box;
58
+ animation: gradient 10s ease infinite;
59
+ z-index: 1;
60
+ }
61
+
62
+ .supporter-effect:after,
63
+ .supporter-effect-hover:hover:after {
64
+ position: absolute;
65
+ top: 0px;
66
+ bottom: 0px;
67
+ left: 0px;
68
+ right: 0px;
69
+ background: linear-gradient(
70
+ to right,
71
+ rgba(16, 132, 254, 0.15),
72
+ rgba(229, 125, 175, 0.15),
73
+ rgba(254, 36, 29, 0.15),
74
+ rgba(255, 183, 0, 0.15),
75
+ rgba(22, 193, 68, 0.15)
76
+ );
77
+ content: '';
78
+ animation: gradient 10s ease infinite;
79
+ background-size: 400% 400%;
80
+ z-index: -1;
81
+ }
82
+
83
+ @keyframes gradient {
84
+ 0% {
85
+ background-position: 0% 50%;
86
+ }
87
+ 50% {
88
+ background-position: 100% 50%;
89
+ }
90
+ 100% {
91
+ background-position: 0% 50%;
92
+ }
93
+ }
94
+ </style>
@@ -0,0 +1,9 @@
1
+ import type { Size } from '../../types.js';
2
+ import type { Snippet } from 'svelte';
3
+ declare const SupporterBadge: import("svelte").Component<{
4
+ effect?: "hover" | "always";
5
+ text?: string;
6
+ size?: Size;
7
+ children?: Snippet;
8
+ }, {}, "">;
9
+ export default SupporterBadge;
@@ -0,0 +1,49 @@
1
+ <script lang="ts">
2
+ import type { Color, Size } from '../../types.js';
3
+ import { cleanClass } from '../../utils.js';
4
+ import type { Snippet } from 'svelte';
5
+ import { tv } from 'tailwind-variants';
6
+
7
+ type Props = {
8
+ color?: Color;
9
+ size?: Size;
10
+ children: Snippet;
11
+ variant?: 'italic';
12
+ fontWeight?: 'light' | 'normal' | 'semi-bold' | 'bold';
13
+ class?: string;
14
+ };
15
+
16
+ const { color, size, fontWeight = 'normal', children, class: className }: Props = $props();
17
+
18
+ const styles = tv({
19
+ variants: {
20
+ color: {
21
+ primary: 'text-primary',
22
+ secondary: 'text-dark',
23
+ success: 'text-success',
24
+ danger: 'text-danger',
25
+ warning: 'text-warning',
26
+ info: 'text-info',
27
+ },
28
+
29
+ size: {
30
+ tiny: 'text-xs',
31
+ small: 'text-sm',
32
+ medium: 'text-md',
33
+ large: 'text-lg',
34
+ giant: 'text-xl',
35
+ },
36
+
37
+ fontWeight: {
38
+ light: 'font-light',
39
+ normal: 'font-normal',
40
+ 'semi-bold': 'font-semibold',
41
+ bold: 'font-bold',
42
+ },
43
+ },
44
+ });
45
+ </script>
46
+
47
+ <p class={cleanClass(styles({ color, size, fontWeight }), className)}>
48
+ {@render children()}
49
+ </p>
@@ -0,0 +1,11 @@
1
+ import type { Color, Size } from '../../types.js';
2
+ import type { Snippet } from 'svelte';
3
+ declare const Text: import("svelte").Component<{
4
+ color?: Color;
5
+ size?: Size;
6
+ children: Snippet;
7
+ variant?: "italic";
8
+ fontWeight?: "light" | "normal" | "semi-bold" | "bold";
9
+ class?: string;
10
+ }, {}, "">;
11
+ export default Text;
@@ -0,0 +1,6 @@
1
+ export declare enum ContextKey {
2
+ Card = "card",
3
+ CardHeader = "card-header",
4
+ CardBody = "card-body",
5
+ CardFooter = "card-footer"
6
+ }
@@ -0,0 +1,7 @@
1
+ export var ContextKey;
2
+ (function (ContextKey) {
3
+ ContextKey["Card"] = "card";
4
+ ContextKey["CardHeader"] = "card-header";
5
+ ContextKey["CardBody"] = "card-body";
6
+ ContextKey["CardFooter"] = "card-footer";
7
+ })(ContextKey || (ContextKey = {}));
package/dist/index.d.ts CHANGED
@@ -1,2 +1,23 @@
1
- export * from './components/index.js';
1
+ export { default as Alert } from './components/Alert/Alert.svelte';
2
+ export { default as Button } from './components/Button/Button.svelte';
3
+ export { default as Card } from './components/Card/Card.svelte';
4
+ export { default as CardBody } from './components/Card/CardBody.svelte';
5
+ export { default as CardDescription } from './components/Card/CardDescription.svelte';
6
+ export { default as CardFooter } from './components/Card/CardFooter.svelte';
7
+ export { default as CardHeader } from './components/Card/CardHeader.svelte';
8
+ export { default as CardTitle } from './components/Card/CardTitle.svelte';
9
+ export { default as CloseButton } from './components/CloseButton/CloseButton.svelte';
10
+ export { default as Checkbox } from './components/Form/Checkbox.svelte';
11
+ export { default as Input } from './components/Form/Input.svelte';
12
+ export { default as Label } from './components/Form/Label.svelte';
13
+ export { default as Heading } from './components/Heading/Heading.svelte';
14
+ export { default as Icon } from './components/Icon/Icon.svelte';
15
+ export { default as IconButton } from './components/IconButton/IconButton.svelte';
16
+ export { default as Link } from './components/Link/Link.svelte';
17
+ export { default as SupporterBadge } from './components/SupporterBadge/SupporterBadge.svelte';
18
+ export { default as Logo } from './components/Logo/Logo.svelte';
19
+ export { default as HStack } from './components/Stack/HStack.svelte';
20
+ export { default as Stack } from './components/Stack/Stack.svelte';
21
+ export { default as VStack } from './components/Stack/VStack.svelte';
22
+ export { default as Text } from './components/Text/Text.svelte';
2
23
  export * from './types.js';
package/dist/index.js CHANGED
@@ -1,2 +1,23 @@
1
- export * from './components/index.js';
1
+ export { default as Alert } from './components/Alert/Alert.svelte';
2
+ export { default as Button } from './components/Button/Button.svelte';
3
+ export { default as Card } from './components/Card/Card.svelte';
4
+ export { default as CardBody } from './components/Card/CardBody.svelte';
5
+ export { default as CardDescription } from './components/Card/CardDescription.svelte';
6
+ export { default as CardFooter } from './components/Card/CardFooter.svelte';
7
+ export { default as CardHeader } from './components/Card/CardHeader.svelte';
8
+ export { default as CardTitle } from './components/Card/CardTitle.svelte';
9
+ export { default as CloseButton } from './components/CloseButton/CloseButton.svelte';
10
+ export { default as Checkbox } from './components/Form/Checkbox.svelte';
11
+ export { default as Input } from './components/Form/Input.svelte';
12
+ export { default as Label } from './components/Form/Label.svelte';
13
+ export { default as Heading } from './components/Heading/Heading.svelte';
14
+ export { default as Icon } from './components/Icon/Icon.svelte';
15
+ export { default as IconButton } from './components/IconButton/IconButton.svelte';
16
+ export { default as Link } from './components/Link/Link.svelte';
17
+ export { default as SupporterBadge } from './components/SupporterBadge/SupporterBadge.svelte';
18
+ export { default as Logo } from './components/Logo/Logo.svelte';
19
+ export { default as HStack } from './components/Stack/HStack.svelte';
20
+ export { default as Stack } from './components/Stack/Stack.svelte';
21
+ export { default as VStack } from './components/Stack/VStack.svelte';
22
+ export { default as Text } from './components/Text/Text.svelte';
2
23
  export * from './types.js';
@@ -1,114 +1,122 @@
1
1
  <script lang="ts">
2
- import type { Color, Shape, Size } from '../types.js';
2
+ import type { ButtonProps } from '../types.js';
3
3
  import { cleanClass } from '../utils.js';
4
4
  import { Button as ButtonPrimitive } from 'bits-ui';
5
5
  import type { HTMLAnchorAttributes, HTMLButtonAttributes } from 'svelte/elements';
6
+ import { twMerge } from 'tailwind-merge';
6
7
  import { tv } from 'tailwind-variants';
7
8
 
8
- type ButtonVariant = 'filled' | 'outline' | 'ghost' | 'hero';
9
- type ButtonProps = {
10
- class?: string;
11
- color?: Color;
12
- size?: Size;
13
- shape?: Shape;
14
- variant?: ButtonVariant;
15
- fullWidth?: boolean;
16
- } & (({ href?: never } & HTMLButtonAttributes) | ({ href: string } & HTMLAnchorAttributes));
17
-
18
- const asOverride = (variant: ButtonVariant, colors: Record<Color, string>) =>
19
- (Object.keys(colors) as Color[]).map((color) => ({ variant, color, class: colors[color] }));
20
-
21
- const colorPlaceholder = {
22
- primary: '',
23
- secondary: '',
24
- success: '',
25
- danger: '',
26
- warning: '',
27
- info: '',
9
+ type InternalButtonProps = ButtonProps & {
10
+ /** when true, button width to height ratio is 1:1 */
11
+ icon?: boolean;
28
12
  };
29
13
 
30
- const variantPlaceholder = {
31
- outline: '',
32
- filled: '',
33
- ghost: '',
34
- hero: '',
35
- };
14
+ const {
15
+ type = 'button',
16
+ href,
17
+ variant = 'filled',
18
+ color = 'primary',
19
+ shape = 'semi-round',
20
+ size = 'medium',
21
+ fullWidth = false,
22
+ icon = false,
23
+ class: className = '',
24
+ children,
25
+ ...restProps
26
+ }: InternalButtonProps = $props();
36
27
 
37
28
  const buttonVariants = tv({
38
29
  base: 'ring-offset-background focus-visible:ring-ring flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50',
39
30
  variants: {
40
31
  shape: {
41
32
  rectangle: 'rounded-none',
42
- 'semi-round': 'rounded-lg',
33
+ 'semi-round': 'rounded-xl',
43
34
  round: 'rounded-full',
44
35
  },
45
- size: {
46
- tiny: 'px-2 py-1 text-xs',
47
- small: 'px-2 py-1 text-sm',
48
- medium: 'px-4 py-2 text-md',
49
- large: 'px-4 py-2 text-lg',
50
- giant: 'px-8 py-4 text-xl',
51
- },
52
36
  fullWidth: {
53
37
  true: 'w-full',
54
38
  },
55
- color: colorPlaceholder,
56
- variant: variantPlaceholder,
57
- },
58
- compoundVariants: [
59
- ...asOverride('filled', {
39
+ textPadding: {
40
+ tiny: 'px-2 py-1',
41
+ small: 'px-2 py-1',
42
+ medium: 'px-4 py-2',
43
+ large: 'px-4 py-2',
44
+ giant: 'px-8 py-4',
45
+ },
46
+ textSize: {
47
+ tiny: 'text-xs',
48
+ small: 'text-sm',
49
+ medium: 'text-md',
50
+ large: 'text-lg',
51
+ giant: 'text-xl',
52
+ },
53
+ iconSize: {
54
+ tiny: 'h-4 w-4 text-xs',
55
+ small: 'h-6 w-6 text-sm',
56
+ medium: 'h-8 w-8 text-md',
57
+ large: 'h-10 w-10 text-lg',
58
+ giant: 'h-12 w-12 text-lg',
59
+ },
60
+ roundedSize: {
61
+ tiny: 'rounded-md',
62
+ small: 'rounded-md',
63
+ medium: 'rounded-lg',
64
+ large: 'rounded-lg',
65
+ giant: 'rounded-lg',
66
+ },
67
+ filledColor: {
60
68
  primary: 'bg-primary text-light hover:bg-primary/80',
61
69
  secondary: 'bg-dark text-light hover:bg-dark/80',
62
70
  success: 'bg-success text-light hover:bg-success/80',
63
71
  danger: 'bg-danger text-light hover:bg-danger/80',
64
72
  warning: 'bg-warning text-light hover:bg-warning/80',
65
73
  info: 'bg-info text-light hover:bg-info/80',
66
- }),
67
-
68
- ...asOverride('outline', {
74
+ },
75
+ outlineColor: {
69
76
  primary: 'bg-primary/10 text-primary border border-primary hover:bg-primary/20',
70
77
  secondary: 'bg-dark/10 text-dark border border-dark hover:bg-dark/20',
71
78
  success: 'bg-success/10 text-success border border-success hover:bg-success/20',
72
79
  danger: 'bg-danger/10 text-danger border border-danger hover:bg-danger/20',
73
80
  warning: 'bg-warning/10 text-warning border border-warning hover:bg-warning/20',
74
81
  info: 'bg-info/10 text-info border border-info hover:bg-info/20',
75
- }),
76
-
77
- ...asOverride('ghost', {
78
- primary: 'text-primary hover:bg-primary/10',
79
- secondary: 'text-dark hover:bg-dark/10',
80
- success: 'text-success hover:bg-success/10',
81
- danger: 'text-danger hover:bg-danger/10',
82
- warning: 'text-warning hover:bg-warning/10',
83
- info: 'text-info hover:bg-info/10',
84
- }),
85
-
86
- ...asOverride('hero', {
82
+ },
83
+ heroColor: {
87
84
  primary: 'bg-gradient-to-tr from-primary to-primary/60 text-light hover:bg-primary',
88
85
  secondary: 'bg-gradient-to-tr from-dark to-dark/60 text-light hover:bg-dark',
89
86
  success: 'bg-gradient-to-tr from-success to-success/60 text-light hover:bg-success',
90
87
  danger: 'bg-gradient-to-tr from-danger to-danger/60 text-light hover:bg-danger',
91
88
  warning: 'bg-gradient-to-tr from-warning to-warning/60 text-light hover:bg-warning',
92
89
  info: 'bg-gradient-to-tr from-info to-info/60 text-light hover:bg-info',
93
- }),
94
- ],
90
+ },
91
+ ghostColor: {
92
+ primary: 'text-primary hover:bg-primary/10',
93
+ secondary: 'text-dark hover:bg-dark/10',
94
+ success: 'text-success hover:bg-success/10',
95
+ danger: 'text-danger hover:bg-danger/10',
96
+ warning: 'text-warning hover:bg-warning/10',
97
+ info: 'text-info hover:bg-info/10',
98
+ },
99
+ },
95
100
  });
96
101
 
97
- const {
98
- type = 'button',
99
- href,
100
- variant = 'filled',
101
- color = 'primary',
102
- shape = 'semi-round',
103
- size = 'medium',
104
- fullWidth = false,
105
- class: className = '',
106
- children,
107
- ...restProps
108
- }: ButtonProps = $props();
109
-
110
102
  const classList = $derived(
111
- cleanClass(buttonVariants({ variant, color, shape, size, fullWidth }), className),
103
+ cleanClass(
104
+ twMerge(
105
+ buttonVariants({
106
+ shape,
107
+ fullWidth,
108
+ textPadding: icon ? undefined : size,
109
+ textSize: size,
110
+ iconSize: icon ? size : undefined,
111
+ roundedSize: shape === 'semi-round' ? size : undefined,
112
+ filledColor: variant === 'filled' ? color : undefined,
113
+ outlineColor: variant === 'outline' ? color : undefined,
114
+ heroColor: variant === 'hero' ? color : undefined,
115
+ ghostColor: variant === 'ghost' ? color : undefined,
116
+ }),
117
+ className,
118
+ ),
119
+ ),
112
120
  );
113
121
  </script>
114
122
 
@@ -0,0 +1,6 @@
1
+ import type { ButtonProps } from '../types.js';
2
+ declare const Button: import("svelte").Component<ButtonProps & {
3
+ /** when true, button width to height ratio is 1:1 */
4
+ icon?: boolean;
5
+ }, {}, "">;
6
+ export default Button;