yaxa-svelte 1.0.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 (169) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +163 -0
  3. package/dist/assets/favicon.svg +15 -0
  4. package/dist/components/elements/Avatar.svelte +106 -0
  5. package/dist/components/elements/Avatar.svelte.d.ts +40 -0
  6. package/dist/components/elements/AvatarGroup.svelte +18 -0
  7. package/dist/components/elements/AvatarGroup.svelte.d.ts +8 -0
  8. package/dist/components/elements/Badge.svelte +202 -0
  9. package/dist/components/elements/Badge.svelte.d.ts +75 -0
  10. package/dist/components/elements/Button.svelte +300 -0
  11. package/dist/components/elements/Button.svelte.d.ts +109 -0
  12. package/dist/components/elements/ButtonGroup.svelte +22 -0
  13. package/dist/components/elements/ButtonGroup.svelte.d.ts +9 -0
  14. package/dist/components/elements/Chip.svelte +117 -0
  15. package/dist/components/elements/Chip.svelte.d.ts +15 -0
  16. package/dist/components/elements/DataTable.svelte +222 -0
  17. package/dist/components/elements/DataTable.svelte.d.ts +43 -0
  18. package/dist/components/elements/Icon.svelte +87 -0
  19. package/dist/components/elements/Icon.svelte.d.ts +10 -0
  20. package/dist/components/elements/Kbd.svelte +37 -0
  21. package/dist/components/elements/Kbd.svelte.d.ts +32 -0
  22. package/dist/components/elements/Link.svelte +63 -0
  23. package/dist/components/elements/Link.svelte.d.ts +15 -0
  24. package/dist/components/elements/Logo.svelte +77 -0
  25. package/dist/components/elements/Logo.svelte.d.ts +9 -0
  26. package/dist/components/elements/Meter.svelte +87 -0
  27. package/dist/components/elements/Meter.svelte.d.ts +14 -0
  28. package/dist/components/elements/Progress.svelte +63 -0
  29. package/dist/components/elements/Progress.svelte.d.ts +49 -0
  30. package/dist/components/elements/Skeleton.svelte +12 -0
  31. package/dist/components/elements/Skeleton.svelte.d.ts +6 -0
  32. package/dist/components/elements/Spinner.svelte +39 -0
  33. package/dist/components/elements/Spinner.svelte.d.ts +7 -0
  34. package/dist/components/forms/Checkbox.svelte +77 -0
  35. package/dist/components/forms/Checkbox.svelte.d.ts +17 -0
  36. package/dist/components/forms/ColorPicker.svelte +142 -0
  37. package/dist/components/forms/ColorPicker.svelte.d.ts +10 -0
  38. package/dist/components/forms/Form.svelte +84 -0
  39. package/dist/components/forms/Form.svelte.d.ts +14 -0
  40. package/dist/components/forms/FormField.svelte +56 -0
  41. package/dist/components/forms/FormField.svelte.d.ts +14 -0
  42. package/dist/components/forms/Input.svelte +138 -0
  43. package/dist/components/forms/Input.svelte.d.ts +58 -0
  44. package/dist/components/forms/RadioGroup.svelte +74 -0
  45. package/dist/components/forms/RadioGroup.svelte.d.ts +17 -0
  46. package/dist/components/forms/Select.svelte +91 -0
  47. package/dist/components/forms/Select.svelte.d.ts +50 -0
  48. package/dist/components/forms/Slider.svelte +37 -0
  49. package/dist/components/forms/Slider.svelte.d.ts +12 -0
  50. package/dist/components/forms/Switch.svelte +81 -0
  51. package/dist/components/forms/Switch.svelte.d.ts +53 -0
  52. package/dist/components/forms/Textarea.svelte +73 -0
  53. package/dist/components/forms/Textarea.svelte.d.ts +64 -0
  54. package/dist/components/layout/Card.svelte +89 -0
  55. package/dist/components/layout/Card.svelte.d.ts +64 -0
  56. package/dist/components/layout/Container.svelte +36 -0
  57. package/dist/components/layout/Container.svelte.d.ts +37 -0
  58. package/dist/components/layout/Divider.svelte +45 -0
  59. package/dist/components/layout/Divider.svelte.d.ts +11 -0
  60. package/dist/components/layout/Footer.svelte +96 -0
  61. package/dist/components/layout/Footer.svelte.d.ts +10 -0
  62. package/dist/components/layout/Header.svelte +175 -0
  63. package/dist/components/layout/Header.svelte.d.ts +12 -0
  64. package/dist/components/layout/Section.svelte +62 -0
  65. package/dist/components/layout/Section.svelte.d.ts +14 -0
  66. package/dist/components/layout/YaxaApp.svelte +48 -0
  67. package/dist/components/layout/YaxaApp.svelte.d.ts +12 -0
  68. package/dist/components/navigation/Breadcrumb.svelte +58 -0
  69. package/dist/components/navigation/Breadcrumb.svelte.d.ts +13 -0
  70. package/dist/components/navigation/CommandPalette.svelte +201 -0
  71. package/dist/components/navigation/CommandPalette.svelte.d.ts +19 -0
  72. package/dist/components/navigation/DropdownMenu.svelte +75 -0
  73. package/dist/components/navigation/DropdownMenu.svelte.d.ts +20 -0
  74. package/dist/components/navigation/Pagination.svelte +106 -0
  75. package/dist/components/navigation/Pagination.svelte.d.ts +10 -0
  76. package/dist/components/navigation/Tabs.svelte +91 -0
  77. package/dist/components/navigation/Tabs.svelte.d.ts +18 -0
  78. package/dist/components/overlays/Accordion.svelte +54 -0
  79. package/dist/components/overlays/Accordion.svelte.d.ts +16 -0
  80. package/dist/components/overlays/Alert.svelte +110 -0
  81. package/dist/components/overlays/Alert.svelte.d.ts +37 -0
  82. package/dist/components/overlays/ContextMenu.svelte +67 -0
  83. package/dist/components/overlays/ContextMenu.svelte.d.ts +21 -0
  84. package/dist/components/overlays/Modal.svelte +99 -0
  85. package/dist/components/overlays/Modal.svelte.d.ts +40 -0
  86. package/dist/components/overlays/Popover.svelte +33 -0
  87. package/dist/components/overlays/Popover.svelte.d.ts +11 -0
  88. package/dist/components/overlays/Slideover.svelte +102 -0
  89. package/dist/components/overlays/Slideover.svelte.d.ts +37 -0
  90. package/dist/components/overlays/Tooltip.svelte +39 -0
  91. package/dist/components/overlays/Tooltip.svelte.d.ts +12 -0
  92. package/dist/components/saas/AuthCard.svelte +273 -0
  93. package/dist/components/saas/AuthCard.svelte.d.ts +16 -0
  94. package/dist/components/saas/PricingCard.svelte +166 -0
  95. package/dist/components/saas/PricingCard.svelte.d.ts +19 -0
  96. package/dist/components/saas/PricingTable.svelte +139 -0
  97. package/dist/components/saas/PricingTable.svelte.d.ts +11 -0
  98. package/dist/components/saas/SubscriptionCard.svelte +162 -0
  99. package/dist/components/saas/SubscriptionCard.svelte.d.ts +16 -0
  100. package/dist/components/saas/UserMenu.svelte +137 -0
  101. package/dist/components/saas/UserMenu.svelte.d.ts +19 -0
  102. package/dist/components/seo/Favicons.svelte +22 -0
  103. package/dist/components/seo/Favicons.svelte.d.ts +8 -0
  104. package/dist/components/seo/OgImage.svelte +61 -0
  105. package/dist/components/seo/OgImage.svelte.d.ts +12 -0
  106. package/dist/components/seo/Seo.svelte +170 -0
  107. package/dist/components/seo/Seo.svelte.d.ts +21 -0
  108. package/dist/composables/useAuth.svelte.d.ts +23 -0
  109. package/dist/composables/useAuth.svelte.js +157 -0
  110. package/dist/composables/useClipboard.svelte.d.ts +9 -0
  111. package/dist/composables/useClipboard.svelte.js +36 -0
  112. package/dist/composables/useColorMode.svelte.d.ts +8 -0
  113. package/dist/composables/useColorMode.svelte.js +20 -0
  114. package/dist/composables/useDebounce.svelte.d.ts +3 -0
  115. package/dist/composables/useDebounce.svelte.js +17 -0
  116. package/dist/composables/useMediaQuery.svelte.d.ts +3 -0
  117. package/dist/composables/useMediaQuery.svelte.js +17 -0
  118. package/dist/composables/useShortcuts.svelte.d.ts +10 -0
  119. package/dist/composables/useShortcuts.svelte.js +50 -0
  120. package/dist/composables/useToast.d.ts +19 -0
  121. package/dist/composables/useToast.js +34 -0
  122. package/dist/index.d.ts +101 -0
  123. package/dist/index.js +92 -0
  124. package/dist/server/auth/hook.d.ts +14 -0
  125. package/dist/server/auth/hook.js +36 -0
  126. package/dist/server/auth/index.d.ts +39 -0
  127. package/dist/server/auth/index.js +69 -0
  128. package/dist/server/db/index.d.ts +18 -0
  129. package/dist/server/db/index.js +43 -0
  130. package/dist/server/db/schema-pg.d.ts +977 -0
  131. package/dist/server/db/schema-pg.js +83 -0
  132. package/dist/server/db/schema-sqlite.d.ts +1045 -0
  133. package/dist/server/db/schema-sqlite.js +83 -0
  134. package/dist/server/db/types.d.ts +44 -0
  135. package/dist/server/db/types.js +1 -0
  136. package/dist/server/email/index.d.ts +27 -0
  137. package/dist/server/email/index.js +79 -0
  138. package/dist/server/polar/index.d.ts +29 -0
  139. package/dist/server/polar/index.js +49 -0
  140. package/dist/server/polar/webhook.d.ts +16 -0
  141. package/dist/server/polar/webhook.js +118 -0
  142. package/dist/site/config.d.ts +63 -0
  143. package/dist/site/config.js +48 -0
  144. package/dist/site/context.d.ts +11 -0
  145. package/dist/site/context.js +23 -0
  146. package/dist/site/hook.d.ts +15 -0
  147. package/dist/site/hook.js +38 -0
  148. package/dist/site/manifest.d.ts +6 -0
  149. package/dist/site/manifest.js +32 -0
  150. package/dist/site/og.d.ts +14 -0
  151. package/dist/site/og.js +116 -0
  152. package/dist/site/robots.d.ts +10 -0
  153. package/dist/site/robots.js +54 -0
  154. package/dist/site/schema.d.ts +67 -0
  155. package/dist/site/schema.js +67 -0
  156. package/dist/site/seo-helpers.d.ts +36 -0
  157. package/dist/site/seo-helpers.js +21 -0
  158. package/dist/site/sitemap-xsl.d.ts +6 -0
  159. package/dist/site/sitemap-xsl.js +164 -0
  160. package/dist/site/sitemap.d.ts +20 -0
  161. package/dist/site/sitemap.js +61 -0
  162. package/dist/styles/yaxa.css +84 -0
  163. package/dist/theme/theme.svelte.d.ts +74 -0
  164. package/dist/theme/theme.svelte.js +421 -0
  165. package/dist/utils/cn.d.ts +3 -0
  166. package/dist/utils/cn.js +3 -0
  167. package/dist/vite/index.d.ts +20 -0
  168. package/dist/vite/index.js +29 -0
  169. package/package.json +108 -0
@@ -0,0 +1,73 @@
1
+ <script module lang="ts">
2
+ import { tv, type VariantProps } from '../../utils/cn';
3
+ import type { HTMLTextareaAttributes } from 'svelte/elements';
4
+
5
+ export const textareaVariants = tv({
6
+ base: 'w-full rounded-lg border bg-white dark:bg-neutral-900 text-neutral-900 dark:text-neutral-100 placeholder:text-neutral-400 dark:placeholder:text-neutral-500 focus:outline-none focus:ring-2 transition-all duration-150 disabled:cursor-not-allowed disabled:opacity-50',
7
+ variants: {
8
+ size: {
9
+ sm: 'text-sm p-2.5',
10
+ md: 'text-base p-3',
11
+ lg: 'text-base p-4'
12
+ },
13
+ status: {
14
+ default:
15
+ 'border-neutral-300 dark:border-neutral-700 focus:border-primary-500 focus:ring-primary-500/20',
16
+ error:
17
+ 'border-rose-500 text-rose-900 dark:text-rose-100 focus:border-rose-500 focus:ring-rose-500/20',
18
+ success: 'border-emerald-500 focus:border-emerald-500 focus:ring-emerald-500/20'
19
+ },
20
+ resize: {
21
+ none: 'resize-none',
22
+ vertical: 'resize-y',
23
+ horizontal: 'resize-x',
24
+ both: 'resize'
25
+ }
26
+ },
27
+ defaultVariants: {
28
+ size: 'md',
29
+ status: 'default',
30
+ resize: 'vertical'
31
+ }
32
+ });
33
+
34
+ export type TextareaProps = Omit<HTMLTextareaAttributes, 'size'> &
35
+ VariantProps<typeof textareaVariants> & {
36
+ value?: string;
37
+ rows?: number;
38
+ maxlength?: number;
39
+ showCount?: boolean;
40
+ class?: string;
41
+ };
42
+ </script>
43
+
44
+ <script lang="ts">
45
+ let {
46
+ value = $bindable(''),
47
+ rows = 4,
48
+ maxlength,
49
+ showCount = false,
50
+ size = 'md',
51
+ status = 'default',
52
+ resize = 'vertical',
53
+ class: className = '',
54
+ ...restProps
55
+ }: TextareaProps = $props();
56
+
57
+ let charCount = $derived(value ? value.length : 0);
58
+ </script>
59
+
60
+ <div class="relative w-full">
61
+ <textarea
62
+ bind:value
63
+ {rows}
64
+ {maxlength}
65
+ class={textareaVariants({ size, status, resize, class: className })}
66
+ {...restProps}></textarea>
67
+
68
+ {#if showCount && maxlength}
69
+ <div class="mt-1 flex justify-end text-sm text-neutral-500 dark:text-neutral-400">
70
+ {charCount} / {maxlength}
71
+ </div>
72
+ {/if}
73
+ </div>
@@ -0,0 +1,64 @@
1
+ import { type VariantProps } from '../../utils/cn';
2
+ import type { HTMLTextareaAttributes } from 'svelte/elements';
3
+ export declare const textareaVariants: import("tailwind-variants").TVReturnType<{
4
+ size: {
5
+ sm: "text-sm p-2.5";
6
+ md: "text-base p-3";
7
+ lg: "text-base p-4";
8
+ };
9
+ status: {
10
+ default: "border-neutral-300 dark:border-neutral-700 focus:border-primary-500 focus:ring-primary-500/20";
11
+ error: "border-rose-500 text-rose-900 dark:text-rose-100 focus:border-rose-500 focus:ring-rose-500/20";
12
+ success: "border-emerald-500 focus:border-emerald-500 focus:ring-emerald-500/20";
13
+ };
14
+ resize: {
15
+ none: "resize-none";
16
+ vertical: "resize-y";
17
+ horizontal: "resize-x";
18
+ both: "resize";
19
+ };
20
+ }, undefined, "w-full rounded-lg border bg-white dark:bg-neutral-900 text-neutral-900 dark:text-neutral-100 placeholder:text-neutral-400 dark:placeholder:text-neutral-500 focus:outline-none focus:ring-2 transition-all duration-150 disabled:cursor-not-allowed disabled:opacity-50", {
21
+ size: {
22
+ sm: "text-sm p-2.5";
23
+ md: "text-base p-3";
24
+ lg: "text-base p-4";
25
+ };
26
+ status: {
27
+ default: "border-neutral-300 dark:border-neutral-700 focus:border-primary-500 focus:ring-primary-500/20";
28
+ error: "border-rose-500 text-rose-900 dark:text-rose-100 focus:border-rose-500 focus:ring-rose-500/20";
29
+ success: "border-emerald-500 focus:border-emerald-500 focus:ring-emerald-500/20";
30
+ };
31
+ resize: {
32
+ none: "resize-none";
33
+ vertical: "resize-y";
34
+ horizontal: "resize-x";
35
+ both: "resize";
36
+ };
37
+ }, undefined, import("tailwind-variants").TVReturnTypeLike<{
38
+ size: {
39
+ sm: "text-sm p-2.5";
40
+ md: "text-base p-3";
41
+ lg: "text-base p-4";
42
+ };
43
+ status: {
44
+ default: "border-neutral-300 dark:border-neutral-700 focus:border-primary-500 focus:ring-primary-500/20";
45
+ error: "border-rose-500 text-rose-900 dark:text-rose-100 focus:border-rose-500 focus:ring-rose-500/20";
46
+ success: "border-emerald-500 focus:border-emerald-500 focus:ring-emerald-500/20";
47
+ };
48
+ resize: {
49
+ none: "resize-none";
50
+ vertical: "resize-y";
51
+ horizontal: "resize-x";
52
+ both: "resize";
53
+ };
54
+ }, undefined>>;
55
+ export type TextareaProps = Omit<HTMLTextareaAttributes, 'size'> & VariantProps<typeof textareaVariants> & {
56
+ value?: string;
57
+ rows?: number;
58
+ maxlength?: number;
59
+ showCount?: boolean;
60
+ class?: string;
61
+ };
62
+ declare const Textarea: import("svelte").Component<TextareaProps, {}, "value">;
63
+ type Textarea = ReturnType<typeof Textarea>;
64
+ export default Textarea;
@@ -0,0 +1,89 @@
1
+ <script module lang="ts">
2
+ import { tv, type VariantProps } from '../../utils/cn';
3
+ import type { Snippet } from 'svelte';
4
+
5
+ export const cardVariants = tv({
6
+ base: 'rounded-xl transition-all duration-200 overflow-hidden',
7
+ variants: {
8
+ variant: {
9
+ outline:
10
+ 'border border-neutral-200 bg-white/80 backdrop-blur-xs shadow-xs dark:border-neutral-800 dark:bg-neutral-900/80',
11
+ solid: 'bg-white shadow-md dark:bg-neutral-900',
12
+ soft: 'bg-neutral-50 dark:bg-neutral-900/50',
13
+ subtle:
14
+ 'border border-neutral-200/60 bg-neutral-50/50 dark:border-neutral-800/60 dark:bg-neutral-900/40'
15
+ },
16
+ hover: {
17
+ true: 'hover:shadow-md hover:border-neutral-300 dark:hover:border-neutral-700 hover:-translate-y-0.5'
18
+ },
19
+ padding: {
20
+ none: '',
21
+ sm: 'p-4',
22
+ md: 'p-6',
23
+ lg: 'p-8'
24
+ }
25
+ },
26
+ defaultVariants: {
27
+ variant: 'outline',
28
+ hover: false,
29
+ padding: 'md'
30
+ }
31
+ });
32
+
33
+ export type CardProps = VariantProps<typeof cardVariants> & {
34
+ id?: string;
35
+ class?: string;
36
+ headerClass?: string;
37
+ bodyClass?: string;
38
+ footerClass?: string;
39
+ header?: Snippet;
40
+ footer?: Snippet;
41
+ children?: Snippet;
42
+ };
43
+ </script>
44
+
45
+ <script lang="ts">
46
+ let {
47
+ id,
48
+ variant = 'outline',
49
+ hover = false,
50
+ padding = 'md',
51
+ class: className = '',
52
+ headerClass = '',
53
+ bodyClass = '',
54
+ footerClass = '',
55
+ header,
56
+ footer,
57
+ children
58
+ }: CardProps = $props();
59
+ </script>
60
+
61
+ <div {id} class={cardVariants({ variant, hover, class: className })}>
62
+ {#if header}
63
+ <div class="border-b border-neutral-200 px-6 py-4 dark:border-neutral-800 {headerClass}">
64
+ {@render header()}
65
+ </div>
66
+ {/if}
67
+
68
+ {#if children}
69
+ <div
70
+ class="{padding === 'none'
71
+ ? ''
72
+ : padding === 'sm'
73
+ ? 'p-4'
74
+ : padding === 'lg'
75
+ ? 'p-8'
76
+ : 'p-6'} {bodyClass}"
77
+ >
78
+ {@render children()}
79
+ </div>
80
+ {/if}
81
+
82
+ {#if footer}
83
+ <div
84
+ class="border-t border-neutral-200 bg-neutral-50/50 px-6 py-4 dark:border-neutral-800 dark:bg-neutral-900/50 {footerClass}"
85
+ >
86
+ {@render footer()}
87
+ </div>
88
+ {/if}
89
+ </div>
@@ -0,0 +1,64 @@
1
+ import { type VariantProps } from '../../utils/cn';
2
+ import type { Snippet } from 'svelte';
3
+ export declare const cardVariants: import("tailwind-variants").TVReturnType<{
4
+ variant: {
5
+ outline: "border border-neutral-200 bg-white/80 backdrop-blur-xs shadow-xs dark:border-neutral-800 dark:bg-neutral-900/80";
6
+ solid: "bg-white shadow-md dark:bg-neutral-900";
7
+ soft: "bg-neutral-50 dark:bg-neutral-900/50";
8
+ subtle: "border border-neutral-200/60 bg-neutral-50/50 dark:border-neutral-800/60 dark:bg-neutral-900/40";
9
+ };
10
+ hover: {
11
+ true: "hover:shadow-md hover:border-neutral-300 dark:hover:border-neutral-700 hover:-translate-y-0.5";
12
+ };
13
+ padding: {
14
+ none: "";
15
+ sm: "p-4";
16
+ md: "p-6";
17
+ lg: "p-8";
18
+ };
19
+ }, undefined, "rounded-xl transition-all duration-200 overflow-hidden", {
20
+ variant: {
21
+ outline: "border border-neutral-200 bg-white/80 backdrop-blur-xs shadow-xs dark:border-neutral-800 dark:bg-neutral-900/80";
22
+ solid: "bg-white shadow-md dark:bg-neutral-900";
23
+ soft: "bg-neutral-50 dark:bg-neutral-900/50";
24
+ subtle: "border border-neutral-200/60 bg-neutral-50/50 dark:border-neutral-800/60 dark:bg-neutral-900/40";
25
+ };
26
+ hover: {
27
+ true: "hover:shadow-md hover:border-neutral-300 dark:hover:border-neutral-700 hover:-translate-y-0.5";
28
+ };
29
+ padding: {
30
+ none: "";
31
+ sm: "p-4";
32
+ md: "p-6";
33
+ lg: "p-8";
34
+ };
35
+ }, undefined, import("tailwind-variants").TVReturnTypeLike<{
36
+ variant: {
37
+ outline: "border border-neutral-200 bg-white/80 backdrop-blur-xs shadow-xs dark:border-neutral-800 dark:bg-neutral-900/80";
38
+ solid: "bg-white shadow-md dark:bg-neutral-900";
39
+ soft: "bg-neutral-50 dark:bg-neutral-900/50";
40
+ subtle: "border border-neutral-200/60 bg-neutral-50/50 dark:border-neutral-800/60 dark:bg-neutral-900/40";
41
+ };
42
+ hover: {
43
+ true: "hover:shadow-md hover:border-neutral-300 dark:hover:border-neutral-700 hover:-translate-y-0.5";
44
+ };
45
+ padding: {
46
+ none: "";
47
+ sm: "p-4";
48
+ md: "p-6";
49
+ lg: "p-8";
50
+ };
51
+ }, undefined>>;
52
+ export type CardProps = VariantProps<typeof cardVariants> & {
53
+ id?: string;
54
+ class?: string;
55
+ headerClass?: string;
56
+ bodyClass?: string;
57
+ footerClass?: string;
58
+ header?: Snippet;
59
+ footer?: Snippet;
60
+ children?: Snippet;
61
+ };
62
+ declare const Card: import("svelte").Component<CardProps, {}, "">;
63
+ type Card = ReturnType<typeof Card>;
64
+ export default Card;
@@ -0,0 +1,36 @@
1
+ <script module lang="ts">
2
+ import { tv, type VariantProps } from '../../utils/cn';
3
+ import type { Snippet } from 'svelte';
4
+
5
+ export const containerVariants = tv({
6
+ base: 'mx-auto px-4 sm:px-6 lg:px-8 w-full',
7
+ variants: {
8
+ size: {
9
+ sm: 'max-w-3xl',
10
+ md: 'max-w-5xl',
11
+ lg: 'max-w-7xl',
12
+ xl: 'max-w-(--breakpoint-xl)',
13
+ '2xl': 'max-w-(--breakpoint-2xl)',
14
+ full: 'max-w-full'
15
+ }
16
+ },
17
+ defaultVariants: {
18
+ size: 'lg'
19
+ }
20
+ });
21
+
22
+ export type ContainerProps = VariantProps<typeof containerVariants> & {
23
+ class?: string;
24
+ children?: Snippet;
25
+ };
26
+ </script>
27
+
28
+ <script lang="ts">
29
+ let { size = 'lg', class: className = '', children }: ContainerProps = $props();
30
+ </script>
31
+
32
+ <div class={containerVariants({ size, class: className })}>
33
+ {#if children}
34
+ {@render children()}
35
+ {/if}
36
+ </div>
@@ -0,0 +1,37 @@
1
+ import { type VariantProps } from '../../utils/cn';
2
+ import type { Snippet } from 'svelte';
3
+ export declare const containerVariants: import("tailwind-variants").TVReturnType<{
4
+ size: {
5
+ sm: "max-w-3xl";
6
+ md: "max-w-5xl";
7
+ lg: "max-w-7xl";
8
+ xl: "max-w-(--breakpoint-xl)";
9
+ '2xl': "max-w-(--breakpoint-2xl)";
10
+ full: "max-w-full";
11
+ };
12
+ }, undefined, "mx-auto px-4 sm:px-6 lg:px-8 w-full", {
13
+ size: {
14
+ sm: "max-w-3xl";
15
+ md: "max-w-5xl";
16
+ lg: "max-w-7xl";
17
+ xl: "max-w-(--breakpoint-xl)";
18
+ '2xl': "max-w-(--breakpoint-2xl)";
19
+ full: "max-w-full";
20
+ };
21
+ }, undefined, import("tailwind-variants").TVReturnTypeLike<{
22
+ size: {
23
+ sm: "max-w-3xl";
24
+ md: "max-w-5xl";
25
+ lg: "max-w-7xl";
26
+ xl: "max-w-(--breakpoint-xl)";
27
+ '2xl': "max-w-(--breakpoint-2xl)";
28
+ full: "max-w-full";
29
+ };
30
+ }, undefined>>;
31
+ export type ContainerProps = VariantProps<typeof containerVariants> & {
32
+ class?: string;
33
+ children?: Snippet;
34
+ };
35
+ declare const Container: import("svelte").Component<ContainerProps, {}, "">;
36
+ type Container = ReturnType<typeof Container>;
37
+ export default Container;
@@ -0,0 +1,45 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from 'svelte';
3
+ import Icon from '../elements/Icon.svelte';
4
+
5
+ interface Props {
6
+ label?: string;
7
+ icon?: string;
8
+ orientation?: 'horizontal' | 'vertical';
9
+ class?: string;
10
+ children?: Snippet;
11
+ }
12
+
13
+ let {
14
+ label,
15
+ icon,
16
+ orientation = 'horizontal',
17
+ class: className = '',
18
+ children
19
+ }: Props = $props();
20
+ </script>
21
+
22
+ {#if orientation === 'vertical'}
23
+ <div
24
+ class="inline-block h-full min-h-[1.5em] w-px self-stretch bg-neutral-200 dark:bg-neutral-800 {className}"
25
+ role="separator"
26
+ aria-orientation="vertical"
27
+ ></div>
28
+ {:else if label || icon || children}
29
+ <div class="relative my-4 flex items-center {className}" role="separator">
30
+ <div class="grow border-t border-neutral-200 dark:border-neutral-800"></div>
31
+ <span class="mx-3 shrink-0 text-sm font-medium text-neutral-500 dark:text-neutral-400">
32
+ {#if icon}
33
+ <Icon name={icon} size="xs" class="mr-1 inline-block" />
34
+ {/if}
35
+ {#if label}
36
+ {label}
37
+ {:else if children}
38
+ {@render children()}
39
+ {/if}
40
+ </span>
41
+ <div class="grow border-t border-neutral-200 dark:border-neutral-800"></div>
42
+ </div>
43
+ {:else}
44
+ <hr class="my-4 border-t border-neutral-200 dark:border-neutral-800 {className}" />
45
+ {/if}
@@ -0,0 +1,11 @@
1
+ import type { Snippet } from 'svelte';
2
+ interface Props {
3
+ label?: string;
4
+ icon?: string;
5
+ orientation?: 'horizontal' | 'vertical';
6
+ class?: string;
7
+ children?: Snippet;
8
+ }
9
+ declare const Divider: import("svelte").Component<Props, {}, "">;
10
+ type Divider = ReturnType<typeof Divider>;
11
+ export default Divider;
@@ -0,0 +1,96 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from 'svelte';
3
+ import type { SiteConfig } from '../../site/config';
4
+ import Container from './Container.svelte';
5
+ import Icon from '../elements/Icon.svelte';
6
+ import Logo from '../elements/Logo.svelte';
7
+ import { getSiteConfig } from '../../site/context';
8
+
9
+ interface Props {
10
+ config?: SiteConfig;
11
+ newsletter?: Snippet;
12
+ class?: string;
13
+ }
14
+
15
+ let { config, newsletter, class: className = '' }: Props = $props();
16
+
17
+ let currentConfig = $derived(config || getSiteConfig());
18
+ let currentYear = new Date().getFullYear();
19
+ </script>
20
+
21
+ <footer
22
+ class="border-t border-neutral-200 bg-white dark:border-neutral-800 dark:bg-neutral-950 {className}"
23
+ >
24
+ <Container size="lg" class="py-12 md:py-16">
25
+ <div class="grid grid-cols-1 gap-8 md:grid-cols-4">
26
+ <!-- Brand Info -->
27
+ <div class="space-y-4 md:col-span-2">
28
+ <a href="/" class="inline-flex items-center gap-2.5 font-bold tracking-tight">
29
+ <Logo size="sm" showText text={currentConfig.name} />
30
+ </a>
31
+ <p class="max-w-sm text-base text-neutral-600 dark:text-neutral-400">
32
+ {currentConfig.description}
33
+ </p>
34
+ </div>
35
+
36
+ <!-- Quick Links -->
37
+ <div>
38
+ <h3 class="text-base font-semibold text-neutral-900 dark:text-white">Navigation</h3>
39
+ <ul class="mt-4 space-y-2.5 text-sm text-neutral-600 dark:text-neutral-400">
40
+ {#each currentConfig.nav || [] as item}
41
+ <li>
42
+ <a
43
+ href={item.href}
44
+ class="transition-colors hover:text-primary-600 dark:hover:text-primary-400"
45
+ >
46
+ {item.label}
47
+ </a>
48
+ </li>
49
+ {/each}
50
+ </ul>
51
+ </div>
52
+
53
+ <!-- Socials & Newsletter -->
54
+ <div>
55
+ <h3 class="text-base font-semibold text-neutral-900 dark:text-white">Community</h3>
56
+ <div class="mt-4 flex items-center gap-3">
57
+ {#if currentConfig.socials?.github}
58
+ <a
59
+ href={currentConfig.socials.github}
60
+ target="_blank"
61
+ rel="noopener noreferrer"
62
+ class="text-neutral-500 hover:text-neutral-900 dark:hover:text-white"
63
+ aria-label="GitHub"
64
+ >
65
+ <Icon name="github" size="sm" />
66
+ </a>
67
+ {/if}
68
+ {#if currentConfig.socials?.twitter}
69
+ <a
70
+ href={currentConfig.socials.twitter}
71
+ target="_blank"
72
+ rel="noopener noreferrer"
73
+ class="text-neutral-500 hover:text-neutral-900 dark:hover:text-white"
74
+ aria-label="Twitter"
75
+ >
76
+ <Icon name="twitter" size="sm" />
77
+ </a>
78
+ {/if}
79
+ </div>
80
+
81
+ {#if newsletter}
82
+ <div class="mt-4">
83
+ {@render newsletter()}
84
+ </div>
85
+ {/if}
86
+ </div>
87
+ </div>
88
+
89
+ <div
90
+ class="mt-12 flex flex-col items-center justify-between border-t border-neutral-200 pt-8 text-sm text-neutral-500 sm:flex-row dark:border-neutral-800 dark:text-neutral-400"
91
+ >
92
+ <p>© {currentYear} {currentConfig.name}. Built for SvelteKit 2.7 & Svelte 5.</p>
93
+ <p class="mt-2 sm:mt-0">Designed for solo developers · 100% DRY.</p>
94
+ </div>
95
+ </Container>
96
+ </footer>
@@ -0,0 +1,10 @@
1
+ import type { Snippet } from 'svelte';
2
+ import type { SiteConfig } from '../../site/config';
3
+ interface Props {
4
+ config?: SiteConfig;
5
+ newsletter?: Snippet;
6
+ class?: string;
7
+ }
8
+ declare const Footer: import("svelte").Component<Props, {}, "">;
9
+ type Footer = ReturnType<typeof Footer>;
10
+ export default Footer;