svelora 3.0.5 → 3.0.7

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 (189) hide show
  1. package/dist/BentoGrid/BentoCard.svelte +45 -0
  2. package/dist/BentoGrid/BentoCard.svelte.d.ts +4 -0
  3. package/dist/BentoGrid/BentoGrid.svelte +9 -0
  4. package/dist/BentoGrid/BentoGrid.svelte.d.ts +4 -0
  5. package/dist/BentoGrid/bento-grid.types.d.ts +47 -0
  6. package/dist/BentoGrid/bento-grid.types.js +1 -0
  7. package/dist/BentoGrid/bento-grid.variants.d.ts +30 -0
  8. package/dist/BentoGrid/bento-grid.variants.js +16 -0
  9. package/dist/BentoGrid/index.d.ts +5 -0
  10. package/dist/BentoGrid/index.js +5 -0
  11. package/dist/Chart/Chart.svelte +47 -0
  12. package/dist/Chart/Chart.svelte.d.ts +4 -0
  13. package/dist/Chart/chart.types.d.ts +20 -0
  14. package/dist/Chart/chart.types.js +1 -0
  15. package/dist/Chart/chart.variants.d.ts +3 -0
  16. package/dist/Chart/chart.variants.js +4 -0
  17. package/dist/Chart/index.d.ts +4 -0
  18. package/dist/Chart/index.js +4 -0
  19. package/dist/Chat/ChatBubble.svelte +30 -0
  20. package/dist/Chat/ChatBubble.svelte.d.ts +4 -0
  21. package/dist/Chat/ChatInput.svelte +50 -0
  22. package/dist/Chat/ChatInput.svelte.d.ts +4 -0
  23. package/dist/Chat/ChatMessage.svelte +15 -0
  24. package/dist/Chat/ChatMessage.svelte.d.ts +4 -0
  25. package/dist/Chat/chat.types.d.ts +63 -0
  26. package/dist/Chat/chat.types.js +1 -0
  27. package/dist/Chat/chat.variants.d.ts +117 -0
  28. package/dist/Chat/chat.variants.js +47 -0
  29. package/dist/Chat/index.d.ts +6 -0
  30. package/dist/Chat/index.js +6 -0
  31. package/dist/ColorPicker/ColorPicker.svelte +109 -0
  32. package/dist/ColorPicker/ColorPicker.svelte.d.ts +4 -0
  33. package/dist/ColorPicker/color-picker.types.d.ts +26 -0
  34. package/dist/ColorPicker/color-picker.types.js +1 -0
  35. package/dist/ColorPicker/color-picker.variants.d.ts +69 -0
  36. package/dist/ColorPicker/color-picker.variants.js +13 -0
  37. package/dist/ColorPicker/index.d.ts +4 -0
  38. package/dist/ColorPicker/index.js +4 -0
  39. package/dist/DateRangePicker/DateRangePicker.svelte +59 -0
  40. package/dist/DateRangePicker/DateRangePicker.svelte.d.ts +4 -0
  41. package/dist/DateRangePicker/date-range-picker.types.d.ts +34 -0
  42. package/dist/DateRangePicker/date-range-picker.types.js +1 -0
  43. package/dist/DateRangePicker/date-range-picker.variants.d.ts +39 -0
  44. package/dist/DateRangePicker/date-range-picker.variants.js +20 -0
  45. package/dist/DateRangePicker/index.d.ts +4 -0
  46. package/dist/DateRangePicker/index.js +4 -0
  47. package/dist/Fonts/fonts.js +3 -1
  48. package/dist/Link/Link.context-harness.svelte +8 -0
  49. package/dist/Link/Link.context-harness.svelte.d.ts +7 -0
  50. package/dist/Link/Link.svelte +57 -30
  51. package/dist/Link/index.d.ts +2 -0
  52. package/dist/Link/index.js +1 -0
  53. package/dist/Link/location-context.d.ts +4 -0
  54. package/dist/Link/location-context.js +1 -0
  55. package/dist/List/List.svelte +14 -0
  56. package/dist/List/List.svelte.d.ts +4 -0
  57. package/dist/List/ListItem.svelte +64 -0
  58. package/dist/List/ListItem.svelte.d.ts +4 -0
  59. package/dist/List/index.d.ts +5 -0
  60. package/dist/List/index.js +5 -0
  61. package/dist/List/list.types.d.ts +62 -0
  62. package/dist/List/list.types.js +1 -0
  63. package/dist/List/list.variants.d.ts +99 -0
  64. package/dist/List/list.variants.js +42 -0
  65. package/dist/Marquee/Marquee.svelte +50 -0
  66. package/dist/Marquee/Marquee.svelte.d.ts +4 -0
  67. package/dist/Marquee/index.d.ts +4 -0
  68. package/dist/Marquee/index.js +4 -0
  69. package/dist/Marquee/marquee.types.d.ts +38 -0
  70. package/dist/Marquee/marquee.types.js +1 -0
  71. package/dist/Marquee/marquee.variants.d.ts +78 -0
  72. package/dist/Marquee/marquee.variants.js +28 -0
  73. package/dist/Menu/Menu.svelte +134 -0
  74. package/dist/Menu/Menu.svelte.d.ts +4 -0
  75. package/dist/Menu/index.d.ts +4 -0
  76. package/dist/Menu/index.js +4 -0
  77. package/dist/Menu/menu.types.d.ts +82 -0
  78. package/dist/Menu/menu.types.js +1 -0
  79. package/dist/Menu/menu.variants.d.ts +46 -0
  80. package/dist/Menu/menu.variants.js +32 -0
  81. package/dist/NumberTicker/NumberTicker.svelte +59 -0
  82. package/dist/NumberTicker/NumberTicker.svelte.d.ts +4 -0
  83. package/dist/NumberTicker/index.d.ts +4 -0
  84. package/dist/NumberTicker/index.js +4 -0
  85. package/dist/NumberTicker/number-ticker.types.d.ts +26 -0
  86. package/dist/NumberTicker/number-ticker.types.js +1 -0
  87. package/dist/NumberTicker/number-ticker.variants.d.ts +27 -0
  88. package/dist/NumberTicker/number-ticker.variants.js +6 -0
  89. package/dist/PasswordInput/PasswordInput.svelte +74 -0
  90. package/dist/PasswordInput/PasswordInput.svelte.d.ts +4 -0
  91. package/dist/PasswordInput/index.d.ts +4 -0
  92. package/dist/PasswordInput/index.js +4 -0
  93. package/dist/PasswordInput/password-input.types.d.ts +18 -0
  94. package/dist/PasswordInput/password-input.types.js +1 -0
  95. package/dist/PasswordInput/password-input.variants.d.ts +57 -0
  96. package/dist/PasswordInput/password-input.variants.js +11 -0
  97. package/dist/Prose/Prose.svelte +13 -0
  98. package/dist/Prose/Prose.svelte.d.ts +4 -0
  99. package/dist/Prose/index.d.ts +4 -0
  100. package/dist/Prose/index.js +4 -0
  101. package/dist/Prose/prose.types.d.ts +22 -0
  102. package/dist/Prose/prose.types.js +1 -0
  103. package/dist/Prose/prose.variants.d.ts +45 -0
  104. package/dist/Prose/prose.variants.js +45 -0
  105. package/dist/Rating/Rating.svelte +93 -0
  106. package/dist/Rating/Rating.svelte.d.ts +4 -0
  107. package/dist/Rating/index.d.ts +4 -0
  108. package/dist/Rating/index.js +4 -0
  109. package/dist/Rating/rating.types.d.ts +59 -0
  110. package/dist/Rating/rating.types.js +1 -0
  111. package/dist/Rating/rating.variants.d.ts +93 -0
  112. package/dist/Rating/rating.variants.js +32 -0
  113. package/dist/Resizable/Resizable.svelte +9 -0
  114. package/dist/Resizable/Resizable.svelte.d.ts +4 -0
  115. package/dist/Resizable/index.d.ts +4 -0
  116. package/dist/Resizable/index.js +4 -0
  117. package/dist/Resizable/resizable.types.d.ts +18 -0
  118. package/dist/Resizable/resizable.types.js +1 -0
  119. package/dist/Resizable/resizable.variants.d.ts +48 -0
  120. package/dist/Resizable/resizable.variants.js +17 -0
  121. package/dist/ScrollArea/ScrollArea.svelte +54 -0
  122. package/dist/ScrollArea/ScrollArea.svelte.d.ts +4 -0
  123. package/dist/ScrollArea/index.d.ts +4 -0
  124. package/dist/ScrollArea/index.js +4 -0
  125. package/dist/ScrollArea/scroll-area.types.d.ts +27 -0
  126. package/dist/ScrollArea/scroll-area.types.js +1 -0
  127. package/dist/ScrollArea/scroll-area.variants.d.ts +45 -0
  128. package/dist/ScrollArea/scroll-area.variants.js +27 -0
  129. package/dist/SelectMenu/SelectMenu.svelte +46 -14
  130. package/dist/Sidebar/Sidebar.svelte +30 -0
  131. package/dist/Sidebar/Sidebar.svelte.d.ts +4 -0
  132. package/dist/Sidebar/index.d.ts +4 -0
  133. package/dist/Sidebar/index.js +4 -0
  134. package/dist/Sidebar/sidebar.types.d.ts +31 -0
  135. package/dist/Sidebar/sidebar.types.js +1 -0
  136. package/dist/Sidebar/sidebar.variants.d.ts +69 -0
  137. package/dist/Sidebar/sidebar.variants.js +23 -0
  138. package/dist/Spotlight/Spotlight.svelte +31 -0
  139. package/dist/Spotlight/Spotlight.svelte.d.ts +4 -0
  140. package/dist/Spotlight/index.d.ts +4 -0
  141. package/dist/Spotlight/index.js +4 -0
  142. package/dist/Spotlight/spotlight.types.d.ts +22 -0
  143. package/dist/Spotlight/spotlight.types.js +1 -0
  144. package/dist/Spotlight/spotlight.variants.d.ts +39 -0
  145. package/dist/Spotlight/spotlight.variants.js +8 -0
  146. package/dist/Stepper/Stepper.svelte +12 -9
  147. package/dist/TagsInput/TagsInput.svelte +100 -0
  148. package/dist/TagsInput/TagsInput.svelte.d.ts +4 -0
  149. package/dist/TagsInput/index.d.ts +4 -0
  150. package/dist/TagsInput/index.js +4 -0
  151. package/dist/TagsInput/tags-input.types.d.ts +32 -0
  152. package/dist/TagsInput/tags-input.types.js +1 -0
  153. package/dist/TagsInput/tags-input.variants.d.ts +45 -0
  154. package/dist/TagsInput/tags-input.variants.js +22 -0
  155. package/dist/TreeView/TreeView.svelte +95 -0
  156. package/dist/TreeView/TreeView.svelte.d.ts +4 -0
  157. package/dist/TreeView/index.d.ts +4 -0
  158. package/dist/TreeView/index.js +4 -0
  159. package/dist/TreeView/tree-view.types.d.ts +68 -0
  160. package/dist/TreeView/tree-view.types.js +1 -0
  161. package/dist/TreeView/tree-view.variants.d.ts +69 -0
  162. package/dist/TreeView/tree-view.variants.js +30 -0
  163. package/dist/docs/navigation.js +162 -0
  164. package/dist/hooks/index.d.ts +14 -0
  165. package/dist/hooks/index.js +9 -0
  166. package/dist/hooks/useDebouncedState.svelte.d.ts +30 -0
  167. package/dist/hooks/useDebouncedState.svelte.js +45 -0
  168. package/dist/hooks/useEventListener.svelte.d.ts +30 -0
  169. package/dist/hooks/useEventListener.svelte.js +16 -0
  170. package/dist/hooks/useFocusTrap.svelte.d.ts +42 -0
  171. package/dist/hooks/useFocusTrap.svelte.js +87 -0
  172. package/dist/hooks/useIntersectionObserver.svelte.d.ts +30 -0
  173. package/dist/hooks/useIntersectionObserver.svelte.js +46 -0
  174. package/dist/hooks/useLocalStorage.svelte.d.ts +39 -0
  175. package/dist/hooks/useLocalStorage.svelte.js +73 -0
  176. package/dist/hooks/useResizeObserver.svelte.d.ts +50 -0
  177. package/dist/hooks/useResizeObserver.svelte.js +71 -0
  178. package/dist/hooks/useScrollLock.svelte.d.ts +28 -0
  179. package/dist/hooks/useScrollLock.svelte.js +79 -0
  180. package/dist/hooks/useThrottle.svelte.d.ts +37 -0
  181. package/dist/hooks/useThrottle.svelte.js +72 -0
  182. package/dist/hooks/useTimers.svelte.d.ts +62 -0
  183. package/dist/hooks/useTimers.svelte.js +90 -0
  184. package/dist/hooks/utils.d.ts +1 -0
  185. package/dist/hooks/utils.js +3 -0
  186. package/dist/index.d.ts +18 -0
  187. package/dist/index.js +18 -0
  188. package/dist/mcp/svelora-docs.data.json +59 -5
  189. package/package.json +8 -6
@@ -0,0 +1,82 @@
1
+ import type { Snippet } from 'svelte';
2
+ import type { ClassNameValue } from 'tailwind-merge';
3
+ import type { MenuVariantProps } from './menu.variants.js';
4
+ export interface MenuItemBase {
5
+ /**
6
+ * Text to display in the menu item.
7
+ */
8
+ label?: string;
9
+ /**
10
+ * Icon to display before the label.
11
+ */
12
+ icon?: string;
13
+ /**
14
+ * Whether the menu item is disabled.
15
+ */
16
+ disabled?: boolean;
17
+ /**
18
+ * Whether the menu item is active/selected.
19
+ */
20
+ active?: boolean;
21
+ /**
22
+ * Additional CSS classes.
23
+ */
24
+ class?: ClassNameValue;
25
+ }
26
+ export interface MenuActionItem extends MenuItemBase {
27
+ type?: 'action' | 'item';
28
+ /**
29
+ * The URL to navigate to when the item is clicked.
30
+ */
31
+ href?: string;
32
+ /**
33
+ * Click handler for the item.
34
+ */
35
+ onClick?: (event: MouseEvent) => void;
36
+ /**
37
+ * Target attribute for link items.
38
+ */
39
+ target?: string;
40
+ }
41
+ export interface MenuGroupItem extends MenuItemBase {
42
+ type: 'group';
43
+ /**
44
+ * Child items to display when the group is expanded.
45
+ */
46
+ items: MenuItems;
47
+ /**
48
+ * Whether the group is currently open/expanded.
49
+ */
50
+ open?: boolean;
51
+ }
52
+ export type MenuItemType = MenuActionItem | MenuGroupItem;
53
+ export type MenuItems = MenuItemType[];
54
+ export interface MenuProps {
55
+ /**
56
+ * The array of menu items to render.
57
+ */
58
+ items?: MenuItems;
59
+ /**
60
+ * Style variant of the menu.
61
+ */
62
+ variant?: MenuVariantProps['variant'];
63
+ /**
64
+ * Whether the menu allows multiple groups to be open at once (false)
65
+ * or acts as an accordion, closing other groups when one opens (true).
66
+ * @default false
67
+ */
68
+ accordion?: boolean;
69
+ /**
70
+ * Auto-detect active state from current URL if using SvelteKit.
71
+ * @default false
72
+ */
73
+ autoActive?: boolean;
74
+ /**
75
+ * Additional CSS classes.
76
+ */
77
+ class?: ClassNameValue;
78
+ /**
79
+ * Custom slot for completely custom rendering of items.
80
+ */
81
+ children?: Snippet;
82
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,46 @@
1
+ import { type VariantProps } from 'tailwind-variants';
2
+ export declare const menuVariants: import("tailwind-variants").TVReturnType<{
3
+ variant: {
4
+ default: {};
5
+ };
6
+ }, {
7
+ base: string;
8
+ group: string;
9
+ groupTrigger: string[];
10
+ groupTriggerActive: string;
11
+ groupContent: string;
12
+ item: string[];
13
+ itemActive: string;
14
+ icon: string;
15
+ chevron: string;
16
+ }, undefined, {
17
+ variant: {
18
+ default: {};
19
+ };
20
+ }, {
21
+ base: string;
22
+ group: string;
23
+ groupTrigger: string[];
24
+ groupTriggerActive: string;
25
+ groupContent: string;
26
+ item: string[];
27
+ itemActive: string;
28
+ icon: string;
29
+ chevron: string;
30
+ }, import("tailwind-variants").TVReturnType<{
31
+ variant: {
32
+ default: {};
33
+ };
34
+ }, {
35
+ base: string;
36
+ group: string;
37
+ groupTrigger: string[];
38
+ groupTriggerActive: string;
39
+ groupContent: string;
40
+ item: string[];
41
+ itemActive: string;
42
+ icon: string;
43
+ chevron: string;
44
+ }, undefined, unknown, unknown, undefined>>;
45
+ export type MenuVariantProps = VariantProps<typeof menuVariants>;
46
+ export type MenuSlots = keyof typeof menuVariants.slots;
@@ -0,0 +1,32 @@
1
+ import { tv } from 'tailwind-variants';
2
+ export const menuVariants = tv({
3
+ slots: {
4
+ base: 'flex flex-col gap-1 w-full',
5
+ group: 'flex flex-col w-full',
6
+ groupTrigger: [
7
+ 'flex items-center justify-between w-full px-3 py-2 text-sm font-medium rounded-md',
8
+ 'transition-colors duration-200 outline-none focus-visible:ring-2 focus-visible:ring-outline',
9
+ 'text-on-surface hover:bg-surface-container-highest',
10
+ 'disabled:opacity-50 disabled:cursor-not-allowed'
11
+ ],
12
+ groupTriggerActive: 'bg-primary-container text-on-primary-container',
13
+ groupContent: 'flex flex-col gap-1 pl-4 mt-1',
14
+ item: [
15
+ 'flex items-center w-full px-3 py-2 text-sm font-medium rounded-md',
16
+ 'transition-colors duration-200 outline-none focus-visible:ring-2 focus-visible:ring-outline',
17
+ 'text-on-surface hover:bg-surface-container-highest',
18
+ 'disabled:opacity-50 disabled:cursor-not-allowed'
19
+ ],
20
+ itemActive: 'bg-primary-container text-on-primary-container hover:bg-primary-container/90',
21
+ icon: 'size-5 mr-3 shrink-0',
22
+ chevron: 'size-4 shrink-0 transition-transform duration-200'
23
+ },
24
+ variants: {
25
+ variant: {
26
+ default: {}
27
+ }
28
+ },
29
+ defaultVariants: {
30
+ variant: 'default'
31
+ }
32
+ });
@@ -0,0 +1,59 @@
1
+ <script lang="ts">import { twMerge } from "tailwind-merge";
2
+ import { onMount } from "svelte";
3
+ import { numberTickerVariants } from "./number-ticker.variants.js";
4
+ let { value, duration = 2e3, decimals = 0, delay = 0, class: className, ...restProps } = $props();
5
+ let styles = $derived(numberTickerVariants());
6
+ let displayValue = $state(0);
7
+ let isVisible = $state(false);
8
+ let nodeRef = $state(null);
9
+ // Easing function (easeOutExpo)
10
+ const easeOutExpo = (x) => {
11
+ return x === 1 ? 1 : 1 - 2 ** (-10 * x);
12
+ };
13
+ onMount(() => {
14
+ if (!nodeRef) return;
15
+ let startTime = null;
16
+ let animationFrame;
17
+ const animate = (timestamp) => {
18
+ if (!startTime) startTime = timestamp;
19
+ const progress = timestamp - startTime;
20
+ if (progress < duration) {
21
+ const percentage = progress / duration;
22
+ const easedProgress = easeOutExpo(percentage);
23
+ displayValue = value * easedProgress;
24
+ animationFrame = requestAnimationFrame(animate);
25
+ } else {
26
+ displayValue = value;
27
+ }
28
+ };
29
+ const observer = new IntersectionObserver((entries) => {
30
+ if (entries[0].isIntersecting && !isVisible) {
31
+ isVisible = true;
32
+ setTimeout(() => {
33
+ animationFrame = requestAnimationFrame(animate);
34
+ }, delay);
35
+ }
36
+ }, { threshold: .1 });
37
+ observer.observe(nodeRef);
38
+ return () => {
39
+ observer.disconnect();
40
+ if (animationFrame) cancelAnimationFrame(animationFrame);
41
+ };
42
+ });
43
+ // Re-animate if value changes significantly (optional)
44
+ $effect(() => {
45
+ if (isVisible && value !== undefined) {}
46
+ });
47
+ let formattedValue = $derived(new Intl.NumberFormat("en-US", {
48
+ minimumFractionDigits: decimals,
49
+ maximumFractionDigits: decimals
50
+ }).format(displayValue));
51
+ </script>
52
+
53
+ <span
54
+ bind:this={nodeRef}
55
+ class={twMerge(styles.base() as string, className)}
56
+ {...restProps}
57
+ >
58
+ {formattedValue}
59
+ </span>
@@ -0,0 +1,4 @@
1
+ import type { NumberTickerProps } from './number-ticker.types.js';
2
+ declare const NumberTicker: import("svelte").Component<NumberTickerProps, {}, "">;
3
+ type NumberTicker = ReturnType<typeof NumberTicker>;
4
+ export default NumberTicker;
@@ -0,0 +1,4 @@
1
+ import NumberTicker from './NumberTicker.svelte';
2
+ export { NumberTicker };
3
+ export * from './number-ticker.types.js';
4
+ export * from './number-ticker.variants.js';
@@ -0,0 +1,4 @@
1
+ import NumberTicker from './NumberTicker.svelte';
2
+ export { NumberTicker };
3
+ export * from './number-ticker.types.js';
4
+ export * from './number-ticker.variants.js';
@@ -0,0 +1,26 @@
1
+ import type { HTMLAttributes } from 'svelte/elements';
2
+ export interface NumberTickerProps extends HTMLAttributes<HTMLSpanElement> {
3
+ /**
4
+ * The target number to animate to.
5
+ */
6
+ value: number;
7
+ /**
8
+ * Duration of the animation in milliseconds.
9
+ * @default 2000
10
+ */
11
+ duration?: number;
12
+ /**
13
+ * Whether to show decimal places.
14
+ * @default 0
15
+ */
16
+ decimals?: number;
17
+ /**
18
+ * Start delay in milliseconds.
19
+ * @default 0
20
+ */
21
+ delay?: number;
22
+ /**
23
+ * Additional CSS classes.
24
+ */
25
+ class?: string;
26
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,27 @@
1
+ import { type VariantProps } from 'tailwind-variants';
2
+ export declare const numberTickerVariants: import("tailwind-variants").TVReturnType<{
3
+ [key: string]: {
4
+ [key: string]: import("tailwind-merge").ClassNameValue | {
5
+ base?: import("tailwind-merge").ClassNameValue;
6
+ };
7
+ };
8
+ } | {
9
+ [x: string]: {
10
+ [x: string]: import("tailwind-merge").ClassNameValue | {
11
+ base?: import("tailwind-merge").ClassNameValue;
12
+ };
13
+ };
14
+ } | {}, {
15
+ base: string;
16
+ }, undefined, {
17
+ [key: string]: {
18
+ [key: string]: import("tailwind-merge").ClassNameValue | {
19
+ base?: import("tailwind-merge").ClassNameValue;
20
+ };
21
+ };
22
+ } | {}, {
23
+ base: string;
24
+ }, import("tailwind-variants").TVReturnType<unknown, {
25
+ base: string;
26
+ }, undefined, unknown, unknown, undefined>>;
27
+ export type NumberTickerVariantProps = VariantProps<typeof numberTickerVariants>;
@@ -0,0 +1,6 @@
1
+ import { tv } from 'tailwind-variants';
2
+ export const numberTickerVariants = tv({
3
+ slots: {
4
+ base: 'inline-block font-mono tracking-wider tabular-nums text-surface-900 dark:text-surface-50'
5
+ }
6
+ });
@@ -0,0 +1,74 @@
1
+ <script lang="ts">import { twMerge } from "tailwind-merge";
2
+ import Icon from "../Icon/Icon.svelte";
3
+ import Input from "../Input/Input.svelte";
4
+ import { passwordInputVariants } from "./password-input.variants.js";
5
+ let { value = $bindable(""), showStrength = false, strengthFn, strengthLabels = [
6
+ "Very Weak",
7
+ "Weak",
8
+ "Fair",
9
+ "Good",
10
+ "Strong"
11
+ ], class: className, ...restProps } = $props();
12
+ let styles = $derived(passwordInputVariants());
13
+ let isVisible = $state(false);
14
+ function toggleVisibility() {
15
+ isVisible = !isVisible;
16
+ }
17
+ // Basic strength calculation if none provided
18
+ function calculateStrength(pwd) {
19
+ if (!pwd) return -1;
20
+ let score = 0;
21
+ if (pwd.length > 8) score += 1;
22
+ if (/[A-Z]/.test(pwd) && /[a-z]/.test(pwd)) score += 1;
23
+ if (/[0-9]/.test(pwd)) score += 1;
24
+ if (/[^A-Za-z0-9]/.test(pwd)) score += 1;
25
+ return score;
26
+ }
27
+ let strength = $derived(strengthFn ? strengthFn(String(value ?? "")) : calculateStrength(String(value ?? "")));
28
+ // Colors for the 4 segments based on current strength
29
+ function getSegmentColor(index, currentStrength) {
30
+ if (currentStrength === -1 || index > currentStrength) return "bg-surface-200 dark:bg-surface-700";
31
+ if (currentStrength === 0) return "bg-error-500";
32
+ if (currentStrength === 1) return "bg-warning-500";
33
+ if (currentStrength === 2) return "bg-success-400";
34
+ return "bg-success-500";
35
+ }
36
+ </script>
37
+
38
+ <div class={twMerge(styles.wrapper() as string, className)}>
39
+ <div class={styles.inputWrapper() as string}>
40
+ <Input
41
+ {...restProps as any}
42
+ bind:value
43
+ type={isVisible ? 'text' : 'password'}
44
+ class="w-full pr-10"
45
+ />
46
+
47
+ <button
48
+ type="button"
49
+ class={styles.toggleBtn() as string}
50
+ onclick={toggleVisibility}
51
+ tabindex="-1"
52
+ aria-label={isVisible ? 'Hide password' : 'Show password'}
53
+ >
54
+ {#if isVisible}
55
+ <Icon name="lucide:eye-off" class="w-5 h-5" />
56
+ {:else}
57
+ <Icon name="lucide:eye" class="w-5 h-5" />
58
+ {/if}
59
+ </button>
60
+ </div>
61
+
62
+ {#if showStrength && String(value ?? '').length > 0}
63
+ <div>
64
+ <div class={styles.meterWrapper() as string}>
65
+ {#each Array(4) as _, i}
66
+ <div class={twMerge(styles.meterSegment() as string, getSegmentColor(i, strength))}></div>
67
+ {/each}
68
+ </div>
69
+ <div class={styles.strengthText() as string}>
70
+ {strengthLabels[Math.max(0, strength)]}
71
+ </div>
72
+ </div>
73
+ {/if}
74
+ </div>
@@ -0,0 +1,4 @@
1
+ import type { PasswordInputProps } from './password-input.types.js';
2
+ declare const PasswordInput: import("svelte").Component<PasswordInputProps, {}, "value">;
3
+ type PasswordInput = ReturnType<typeof PasswordInput>;
4
+ export default PasswordInput;
@@ -0,0 +1,4 @@
1
+ import PasswordInput from './PasswordInput.svelte';
2
+ export { PasswordInput };
3
+ export * from './password-input.types.js';
4
+ export * from './password-input.variants.js';
@@ -0,0 +1,4 @@
1
+ import PasswordInput from './PasswordInput.svelte';
2
+ export { PasswordInput };
3
+ export * from './password-input.types.js';
4
+ export * from './password-input.variants.js';
@@ -0,0 +1,18 @@
1
+ import type { InputProps } from '../Input/input.types.js';
2
+ export interface PasswordInputProps extends Omit<InputProps, 'type'> {
3
+ /**
4
+ * Whether to show the password strength meter.
5
+ * @default false
6
+ */
7
+ showStrength?: boolean;
8
+ /**
9
+ * Custom function to calculate password strength (0 to 4).
10
+ * 0 = Very Weak, 4 = Very Strong.
11
+ */
12
+ strengthFn?: (password: string) => number;
13
+ /**
14
+ * Labels for the strength levels (0-4).
15
+ * @default ['Very Weak', 'Weak', 'Fair', 'Good', 'Strong']
16
+ */
17
+ strengthLabels?: [string, string, string, string, string];
18
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,57 @@
1
+ import { type VariantProps } from 'tailwind-variants';
2
+ export declare const passwordInputVariants: import("tailwind-variants").TVReturnType<{
3
+ [key: string]: {
4
+ [key: string]: import("tailwind-merge").ClassNameValue | {
5
+ wrapper?: import("tailwind-merge").ClassNameValue;
6
+ inputWrapper?: import("tailwind-merge").ClassNameValue;
7
+ toggleBtn?: import("tailwind-merge").ClassNameValue;
8
+ meterWrapper?: import("tailwind-merge").ClassNameValue;
9
+ meterSegment?: import("tailwind-merge").ClassNameValue;
10
+ strengthText?: import("tailwind-merge").ClassNameValue;
11
+ };
12
+ };
13
+ } | {
14
+ [x: string]: {
15
+ [x: string]: import("tailwind-merge").ClassNameValue | {
16
+ wrapper?: import("tailwind-merge").ClassNameValue;
17
+ inputWrapper?: import("tailwind-merge").ClassNameValue;
18
+ toggleBtn?: import("tailwind-merge").ClassNameValue;
19
+ meterWrapper?: import("tailwind-merge").ClassNameValue;
20
+ meterSegment?: import("tailwind-merge").ClassNameValue;
21
+ strengthText?: import("tailwind-merge").ClassNameValue;
22
+ };
23
+ };
24
+ } | {}, {
25
+ wrapper: string;
26
+ inputWrapper: string;
27
+ toggleBtn: string;
28
+ meterWrapper: string;
29
+ meterSegment: string;
30
+ strengthText: string;
31
+ }, undefined, {
32
+ [key: string]: {
33
+ [key: string]: import("tailwind-merge").ClassNameValue | {
34
+ wrapper?: import("tailwind-merge").ClassNameValue;
35
+ inputWrapper?: import("tailwind-merge").ClassNameValue;
36
+ toggleBtn?: import("tailwind-merge").ClassNameValue;
37
+ meterWrapper?: import("tailwind-merge").ClassNameValue;
38
+ meterSegment?: import("tailwind-merge").ClassNameValue;
39
+ strengthText?: import("tailwind-merge").ClassNameValue;
40
+ };
41
+ };
42
+ } | {}, {
43
+ wrapper: string;
44
+ inputWrapper: string;
45
+ toggleBtn: string;
46
+ meterWrapper: string;
47
+ meterSegment: string;
48
+ strengthText: string;
49
+ }, import("tailwind-variants").TVReturnType<unknown, {
50
+ wrapper: string;
51
+ inputWrapper: string;
52
+ toggleBtn: string;
53
+ meterWrapper: string;
54
+ meterSegment: string;
55
+ strengthText: string;
56
+ }, undefined, unknown, unknown, undefined>>;
57
+ export type PasswordInputVariantProps = VariantProps<typeof passwordInputVariants>;
@@ -0,0 +1,11 @@
1
+ import { tv } from 'tailwind-variants';
2
+ export const passwordInputVariants = tv({
3
+ slots: {
4
+ wrapper: 'relative flex flex-col gap-2 w-full',
5
+ inputWrapper: 'relative flex items-center w-full',
6
+ toggleBtn: 'absolute right-3 text-surface-500 hover:text-surface-700 dark:hover:text-surface-300 focus:outline-none focus-visible:ring-2 focus-visible:ring-primary rounded-sm transition-colors',
7
+ meterWrapper: 'flex gap-1 h-1.5 w-full mt-1',
8
+ meterSegment: 'flex-1 rounded-full transition-colors duration-300',
9
+ strengthText: 'text-xs text-surface-500 dark:text-surface-400 mt-1 text-right'
10
+ }
11
+ });
@@ -0,0 +1,13 @@
1
+ <script lang="ts">import { twMerge } from "tailwind-merge";
2
+ import { proseVariants } from "./prose.variants.js";
3
+ let { size = "base", html, class: className, children, ...restProps } = $props();
4
+ let styles = $derived(proseVariants({ size }));
5
+ </script>
6
+
7
+ <div class={twMerge(styles.base() as string, className)} {...restProps}>
8
+ {#if html}
9
+ <!-- eslint-disable-next-line svelte/no-at-html-tags -->
10
+ {@html html}
11
+ {/if}
12
+ {@render children?.()}
13
+ </div>
@@ -0,0 +1,4 @@
1
+ import type { ProseProps } from './prose.types.js';
2
+ declare const Prose: import("svelte").Component<ProseProps, {}, "">;
3
+ type Prose = ReturnType<typeof Prose>;
4
+ export default Prose;
@@ -0,0 +1,4 @@
1
+ import Prose from './Prose.svelte';
2
+ export { Prose };
3
+ export * from './prose.types.js';
4
+ export * from './prose.variants.js';
@@ -0,0 +1,4 @@
1
+ import Prose from './Prose.svelte';
2
+ export { Prose };
3
+ export * from './prose.types.js';
4
+ export * from './prose.variants.js';
@@ -0,0 +1,22 @@
1
+ import type { Snippet } from 'svelte';
2
+ import type { HTMLAttributes } from 'svelte/elements';
3
+ import type { ProseVariantProps } from './prose.variants.js';
4
+ export interface ProseProps extends HTMLAttributes<HTMLDivElement> {
5
+ /**
6
+ * Size of the typography text.
7
+ * @default 'base'
8
+ */
9
+ size?: ProseVariantProps['size'];
10
+ /**
11
+ * Html string to render. Usually coming from a markdown parser.
12
+ */
13
+ html?: string;
14
+ /**
15
+ * Additional CSS classes.
16
+ */
17
+ class?: string;
18
+ /**
19
+ * Content inside the prose container.
20
+ */
21
+ children?: Snippet;
22
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,45 @@
1
+ import { type VariantProps } from 'tailwind-variants';
2
+ export declare const proseVariants: import("tailwind-variants").TVReturnType<{
3
+ size: {
4
+ sm: {
5
+ base: string;
6
+ };
7
+ base: {
8
+ base: string;
9
+ };
10
+ lg: {
11
+ base: string;
12
+ };
13
+ };
14
+ }, {
15
+ base: string[];
16
+ }, undefined, {
17
+ size: {
18
+ sm: {
19
+ base: string;
20
+ };
21
+ base: {
22
+ base: string;
23
+ };
24
+ lg: {
25
+ base: string;
26
+ };
27
+ };
28
+ }, {
29
+ base: string[];
30
+ }, import("tailwind-variants").TVReturnType<{
31
+ size: {
32
+ sm: {
33
+ base: string;
34
+ };
35
+ base: {
36
+ base: string;
37
+ };
38
+ lg: {
39
+ base: string;
40
+ };
41
+ };
42
+ }, {
43
+ base: string[];
44
+ }, undefined, unknown, unknown, undefined>>;
45
+ export type ProseVariantProps = VariantProps<typeof proseVariants>;
@@ -0,0 +1,45 @@
1
+ import { tv } from 'tailwind-variants';
2
+ export const proseVariants = tv({
3
+ slots: {
4
+ base: [
5
+ 'text-surface-900 dark:text-surface-50 max-w-none',
6
+ // Paragraphs
7
+ '[&_p]:leading-7 [&_p]:mb-6 [&_p:last-child]:mb-0',
8
+ // Headings
9
+ '[&_h1]:text-4xl [&_h1]:font-extrabold [&_h1]:tracking-tight [&_h1]:mt-0 [&_h1]:mb-6',
10
+ '[&_h2]:text-3xl [&_h2]:font-semibold [&_h2]:tracking-tight [&_h2]:mt-10 [&_h2]:mb-4',
11
+ '[&_h3]:text-2xl [&_h3]:font-semibold [&_h3]:tracking-tight [&_h3]:mt-8 [&_h3]:mb-4',
12
+ '[&_h4]:text-xl [&_h4]:font-semibold [&_h4]:tracking-tight [&_h4]:mt-8 [&_h4]:mb-4',
13
+ // Links
14
+ '[&_a]:font-medium [&_a]:text-primary-600 dark:[&_a]:text-primary-400 [&_a]:underline [&_a]:underline-offset-4 hover:[&_a]:text-primary-500',
15
+ // Blockquotes
16
+ '[&_blockquote]:mt-6 [&_blockquote]:mb-6 [&_blockquote]:border-l-4 [&_blockquote]:border-primary-500 [&_blockquote]:pl-6 [&_blockquote]:italic [&_blockquote]:text-surface-700 dark:[&_blockquote]:text-surface-300',
17
+ // Lists
18
+ '[&_ul]:my-6 [&_ul]:ml-6 [&_ul]:list-disc [&_ul>li]:mt-2',
19
+ '[&_ol]:my-6 [&_ol]:ml-6 [&_ol]:list-decimal [&_ol>li]:mt-2',
20
+ // Code & Pre
21
+ '[&_code]:relative [&_code]:rounded [&_code]:bg-surface-200 dark:[&_code]:bg-surface-800 [&_code]:px-[0.3rem] [&_code]:py-[0.2rem] [&_code]:font-mono [&_code]:text-sm [&_code]:font-semibold',
22
+ '[&_pre]:mb-6 [&_pre]:mt-6 [&_pre]:overflow-x-auto [&_pre]:rounded-lg [&_pre]:bg-surface-900 [&_pre]:py-4 [&_pre]:dark:bg-surface-800',
23
+ '[&_pre_code]:bg-transparent [&_pre_code]:p-0 [&_pre_code]:text-surface-50 [&_pre_code]:font-normal',
24
+ // Images & Media
25
+ '[&_img]:rounded-lg [&_img]:border [&_img]:border-outline-variant [&_video]:rounded-lg',
26
+ // Tables
27
+ '[&_table]:w-full [&_table]:my-6 [&_table]:overflow-y-auto [&_table]:text-left',
28
+ '[&_th]:border [&_th]:border-outline-variant [&_th]:px-4 [&_th]:py-2 [&_th]:font-semibold [&_th]:bg-surface-100 dark:[&_th]:bg-surface-800',
29
+ '[&_td]:border [&_td]:border-outline-variant [&_td]:px-4 [&_td]:py-2',
30
+ '[&_tr:nth-child(even)]:bg-surface-50 dark:[&_tr:nth-child(even)]:bg-surface-900/50',
31
+ // HR
32
+ '[&_hr]:my-8 [&_hr]:border-outline-variant'
33
+ ]
34
+ },
35
+ variants: {
36
+ size: {
37
+ sm: { base: 'text-sm [&_h1]:text-3xl [&_h2]:text-2xl [&_h3]:text-xl' },
38
+ base: { base: 'text-base' },
39
+ lg: { base: 'text-lg [&_h1]:text-5xl [&_h2]:text-4xl [&_h3]:text-3xl' }
40
+ }
41
+ },
42
+ defaultVariants: {
43
+ size: 'base'
44
+ }
45
+ });