zabi-components 4.0.0 → 5.0.1

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 (89) hide show
  1. package/README.md +70 -2
  2. package/dist/SSRSafe.svelte +47 -0
  3. package/dist/SSRSafe.svelte.d.ts +11 -0
  4. package/dist/atoms/Badge.svelte +76 -0
  5. package/dist/atoms/Badge.svelte.d.ts +9 -0
  6. package/dist/atoms/Button.svelte +72 -0
  7. package/dist/atoms/Button.svelte.d.ts +13 -0
  8. package/dist/atoms/Card.svelte +59 -0
  9. package/dist/atoms/Card.svelte.d.ts +12 -0
  10. package/dist/atoms/Checkbox.svelte +60 -0
  11. package/dist/atoms/Checkbox.svelte.d.ts +10 -0
  12. package/dist/atoms/CodeBlock.svelte +125 -0
  13. package/dist/atoms/CodeBlock.svelte.d.ts +8 -0
  14. package/dist/atoms/ColorPicker.svelte +171 -0
  15. package/dist/atoms/ColorPicker.svelte.d.ts +9 -0
  16. package/dist/atoms/FeatureCard.svelte +74 -0
  17. package/dist/atoms/FeatureCard.svelte.d.ts +17 -0
  18. package/dist/atoms/Heading.svelte +5 -0
  19. package/dist/atoms/Heading.svelte.d.ts +7 -0
  20. package/dist/atoms/Input.svelte +98 -0
  21. package/dist/atoms/Input.svelte.d.ts +14 -0
  22. package/dist/atoms/OptimizedImage.svelte +32 -0
  23. package/dist/atoms/OptimizedImage.svelte.d.ts +13 -0
  24. package/dist/atoms/Progress.svelte +61 -0
  25. package/dist/atoms/Progress.svelte.d.ts +9 -0
  26. package/dist/atoms/Select.svelte +85 -0
  27. package/dist/atoms/Select.svelte.d.ts +16 -0
  28. package/dist/atoms/Skeleton.svelte +20 -0
  29. package/dist/atoms/Skeleton.svelte.d.ts +8 -0
  30. package/dist/atoms/Textarea.svelte +116 -0
  31. package/dist/atoms/Textarea.svelte.d.ts +14 -0
  32. package/dist/atoms/ThemeToggle.svelte +89 -0
  33. package/dist/atoms/ThemeToggle.svelte.d.ts +7 -0
  34. package/dist/atoms/Toast.svelte +58 -0
  35. package/dist/atoms/Toast.svelte.d.ts +9 -0
  36. package/dist/atoms/Toggle.svelte +94 -0
  37. package/dist/atoms/Toggle.svelte.d.ts +12 -0
  38. package/dist/atoms/Tooltip.svelte +188 -0
  39. package/dist/atoms/Tooltip.svelte.d.ts +12 -0
  40. package/dist/atoms/index.d.ts +4 -15
  41. package/dist/atoms/index.js +10 -664
  42. package/dist/components/atoms/index.d.ts +10 -0
  43. package/dist/components/atoms/index.d.ts.map +1 -0
  44. package/dist/components/index.d.ts +31 -0
  45. package/dist/components/index.d.ts.map +1 -0
  46. package/dist/components/molecules/index.d.ts +1 -0
  47. package/dist/components/molecules/index.d.ts.map +1 -0
  48. package/dist/components/organisms/index.d.ts +1 -0
  49. package/dist/components/organisms/index.d.ts.map +1 -0
  50. package/dist/index.d.ts +30 -15
  51. package/dist/index.js +74 -0
  52. package/dist/molecules/Alert.svelte +114 -0
  53. package/dist/molecules/Alert.svelte.d.ts +14 -0
  54. package/dist/molecules/ComponentDemo.svelte +96 -0
  55. package/dist/molecules/ComponentDemo.svelte.d.ts +13 -0
  56. package/dist/molecules/ContactForm.svelte +98 -0
  57. package/dist/molecules/ContactForm.svelte.d.ts +10 -0
  58. package/dist/molecules/Dropdown.svelte +128 -0
  59. package/dist/molecules/Dropdown.svelte.d.ts +11 -0
  60. package/dist/molecules/Form.svelte +37 -0
  61. package/dist/molecules/Form.svelte.d.ts +12 -0
  62. package/dist/molecules/ImageUpload.svelte +112 -0
  63. package/dist/molecules/ImageUpload.svelte.d.ts +14 -0
  64. package/dist/molecules/Modal.svelte +85 -0
  65. package/dist/molecules/Modal.svelte.d.ts +13 -0
  66. package/dist/molecules/SlideUp.svelte +73 -0
  67. package/dist/molecules/SlideUp.svelte.d.ts +12 -0
  68. package/dist/molecules/Tabs.svelte +68 -0
  69. package/dist/molecules/Tabs.svelte.d.ts +17 -0
  70. package/dist/molecules/index.d.ts +0 -11
  71. package/dist/molecules/index.js +2 -580
  72. package/dist/organisms/Navbar.svelte +99 -0
  73. package/dist/organisms/Navbar.svelte.d.ts +14 -0
  74. package/dist/organisms/Navigation.svelte +48 -0
  75. package/dist/organisms/Navigation.svelte.d.ts +15 -0
  76. package/dist/organisms/index.d.ts +0 -4
  77. package/dist/organisms/index.js +2 -104
  78. package/dist/routes/lib/ssr-safe.ts +57 -0
  79. package/dist/routes/lib/variant-utils.ts +98 -0
  80. package/dist/zabi-components.css +399 -1
  81. package/package.json +43 -18
  82. package/dist/CodeBlock-Bbv6JfD2.js +0 -422
  83. package/dist/ThemeToggle-Z2Ndc0if.js +0 -42
  84. package/dist/index/index.js +0 -51
  85. package/dist/molecules/KeyValueForm.types.d.ts +0 -11
  86. package/dist/props-BKbHJRuR.js +0 -2213
  87. package/dist/types/index.d.ts +0 -4
  88. package/dist/types/index.js +0 -1
  89. package/dist/vite.svg +0 -1
@@ -0,0 +1,116 @@
1
+ <script lang="ts">
2
+ // SSR-safe ID generation
3
+ function generateId(prefix: string = "id"): string {
4
+ if (typeof window !== "undefined") {
5
+ return `${prefix}-${Math.random().toString(36).substr(2, 9)}`;
6
+ } else {
7
+ return `${prefix}-ssr-${Date.now()}`;
8
+ }
9
+ }
10
+
11
+ // Input variant classes
12
+ function getInputVariantClasses(
13
+ variant: "default" | "success" | "warning" | "error" | "info",
14
+ ): string {
15
+ const variantMap = {
16
+ default:
17
+ "border-gray-300 focus:border-blue-500 focus:ring-blue-500",
18
+ success:
19
+ "border-green-300 focus:border-green-500 focus:ring-green-500",
20
+ warning:
21
+ "border-yellow-300 focus:border-yellow-500 focus:ring-yellow-500",
22
+ error: "border-red-300 focus:border-red-500 focus:ring-red-500",
23
+ info: "border-blue-300 focus:border-blue-500 focus:ring-blue-500",
24
+ };
25
+ return variantMap[variant] || variantMap.default;
26
+ }
27
+
28
+ interface Props {
29
+ value?: string;
30
+ name?: string;
31
+ label?: string;
32
+ placeholder?: string;
33
+ disabled?: boolean;
34
+ rows?: number;
35
+ size?: "sm" | "md" | "lg";
36
+ variant?: "default" | "success" | "warning" | "error";
37
+ oninput?: (event: Event) => void;
38
+ }
39
+
40
+ let {
41
+ value = "",
42
+ name = "",
43
+ label = "",
44
+ placeholder = "",
45
+ disabled = false,
46
+ rows = 4,
47
+ size = "md",
48
+ variant = "default",
49
+ oninput,
50
+ ...restProps
51
+ }: Props = $props();
52
+
53
+ // Generate unique ID - SSR safe (call directly, not in $state)
54
+ const textareaId = generateId("textarea");
55
+
56
+ // Size classes using full class names
57
+ const sizeClass = $derived(() => {
58
+ return size === "sm"
59
+ ? "px-3 py-1.5 text-sm"
60
+ : size === "lg"
61
+ ? "px-5 py-3 text-base"
62
+ : "px-4 py-2 text-sm"; // default md
63
+ });
64
+
65
+ // Variant classes using full class names
66
+ const variantClass = $derived(() => {
67
+ return variant === "success"
68
+ ? "border-green-300 focus:border-green-500 focus:ring-green-500"
69
+ : variant === "warning"
70
+ ? "border-yellow-300 focus:border-yellow-500 focus:ring-yellow-500"
71
+ : variant === "error"
72
+ ? "border-red-300 focus:border-red-500 focus:ring-red-500"
73
+ : "border-gray-300 focus:border-blue-500 focus:ring-blue-500"; // default
74
+ });
75
+
76
+ // Textarea classes using Badge pattern
77
+ const textareaClasses = $derived(() => {
78
+ const baseClasses =
79
+ "w-full rounded-md transition-colors duration-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-surface disabled:opacity-50 disabled:cursor-not-allowed disabled:bg-surface-disabled resize-y";
80
+
81
+ return `${baseClasses} ${sizeClass()} ${variantClass()}`.trim();
82
+ });
83
+
84
+ // Label classes using semantic text colors
85
+ const labelClasses = $derived(
86
+ () => "block text-sm font-medium text-label mb-1",
87
+ );
88
+
89
+ function handleInput(event: Event) {
90
+ const target = event.target as HTMLTextAreaElement;
91
+ value = target.value;
92
+
93
+ // Call the parent's oninput handler if provided
94
+ if (oninput) {
95
+ oninput(event);
96
+ }
97
+ }
98
+ </script>
99
+
100
+ <div>
101
+ {#if label}
102
+ <label for={textareaId} class={labelClasses()}>{label}</label>
103
+ {/if}
104
+
105
+ <textarea
106
+ id={textareaId}
107
+ {name}
108
+ {value}
109
+ {placeholder}
110
+ {disabled}
111
+ {rows}
112
+ class={textareaClasses()}
113
+ oninput={handleInput}
114
+ {...restProps}
115
+ ></textarea>
116
+ </div>
@@ -0,0 +1,14 @@
1
+ interface Props {
2
+ value?: string;
3
+ name?: string;
4
+ label?: string;
5
+ placeholder?: string;
6
+ disabled?: boolean;
7
+ rows?: number;
8
+ size?: "sm" | "md" | "lg";
9
+ variant?: "default" | "success" | "warning" | "error";
10
+ oninput?: (event: Event) => void;
11
+ }
12
+ declare const Textarea: import("svelte").Component<Props, {}, "">;
13
+ type Textarea = ReturnType<typeof Textarea>;
14
+ export default Textarea;
@@ -0,0 +1,89 @@
1
+ <script lang="ts">
2
+ import { onMount } from "svelte";
3
+ // SSR-safe utilities
4
+ function safeLocalStorage(): Storage | undefined {
5
+ return typeof window !== "undefined" ? localStorage : undefined;
6
+ }
7
+
8
+ function safeDocument(): Document | undefined {
9
+ return typeof window !== "undefined" ? document : undefined;
10
+ }
11
+
12
+ interface Props {
13
+ isDark?: boolean;
14
+ onclick?: (event: Event) => void;
15
+ }
16
+
17
+ let { isDark = false, ...restProps }: Props = $props();
18
+
19
+ let mounted = $state(false);
20
+
21
+ onMount(() => {
22
+ mounted = true;
23
+ // Check for saved theme preference or default to light mode
24
+ const storage = safeLocalStorage();
25
+ if (storage) {
26
+ const savedTheme = storage.getItem("theme");
27
+ let prefersDark = false;
28
+
29
+ // Only check media query when mounted and in browser
30
+ if (mounted && typeof window !== "undefined" && window.matchMedia) {
31
+ try {
32
+ prefersDark = window.matchMedia(
33
+ "(prefers-color-scheme: dark)",
34
+ ).matches;
35
+ } catch (e) {
36
+ // Fallback if matchMedia fails
37
+ prefersDark = false;
38
+ }
39
+ }
40
+
41
+ isDark = savedTheme === "dark" || (!savedTheme && prefersDark);
42
+ updateTheme();
43
+ }
44
+ });
45
+
46
+ function toggleTheme(event: Event) {
47
+ isDark = !isDark;
48
+ updateTheme();
49
+ const storage = safeLocalStorage();
50
+ if (mounted && storage) {
51
+ storage.setItem("theme", isDark ? "dark" : "light");
52
+ }
53
+ }
54
+
55
+ function updateTheme() {
56
+ const doc = safeDocument();
57
+ if (mounted && doc) {
58
+ if (isDark) {
59
+ doc.documentElement.classList.add("dark");
60
+ } else {
61
+ doc.documentElement.classList.remove("dark");
62
+ }
63
+ }
64
+ }
65
+ </script>
66
+
67
+ {#if mounted}
68
+ <button
69
+ onclick={toggleTheme}
70
+ class="w-10 h-10 bg-gray-100 hover:bg-gray-200 border border-gray-300 rounded-lg flex items-center justify-center text-gray-700 focus:outline-none focus:ring-2 focus:ring-blue-500"
71
+ aria-label={isDark ? "Switch to light mode" : "Switch to dark mode"}
72
+ {...restProps}
73
+ >
74
+ {#if isDark}
75
+ <span class="text-lg">☀️</span>
76
+ {:else}
77
+ <span class="text-lg">🌙</span>
78
+ {/if}
79
+ </button>
80
+ {:else}
81
+ <!-- SSR fallback -->
82
+ <button
83
+ class="w-10 h-10 bg-gray-100 border border-gray-300 rounded-lg flex items-center justify-center text-gray-700"
84
+ aria-label="Theme toggle"
85
+ {...restProps}
86
+ >
87
+ <span class="text-lg">🌙</span>
88
+ </button>
89
+ {/if}
@@ -0,0 +1,7 @@
1
+ interface Props {
2
+ isDark?: boolean;
3
+ onclick?: (event: Event) => void;
4
+ }
5
+ declare const ThemeToggle: import("svelte").Component<Props, {}, "">;
6
+ type ThemeToggle = ReturnType<typeof ThemeToggle>;
7
+ export default ThemeToggle;
@@ -0,0 +1,58 @@
1
+ <script lang="ts">
2
+ interface Props {
3
+ message?: string;
4
+ type?: "success" | "error" | "warning" | "info";
5
+ closable?: boolean;
6
+ onclick?: (event: Event) => void;
7
+ }
8
+
9
+ let {
10
+ message = "",
11
+ type = "info",
12
+ closable = true,
13
+ onclick,
14
+ ...restProps
15
+ }: Props = $props();
16
+
17
+ let isVisible = $state(true);
18
+
19
+ // Simple type classes
20
+ const typeClasses = {
21
+ success: "bg-green-100 border-green-300 text-success",
22
+ error: "bg-red-100 border-red-300 text-error",
23
+ warning: "bg-yellow-100 border-yellow-300 text-warning",
24
+ info: "bg-blue-100 border-blue-300 text-body",
25
+ };
26
+
27
+ function closeToast(event: Event) {
28
+ isVisible = false;
29
+ if (onclick) {
30
+ onclick(event);
31
+ }
32
+ }
33
+ </script>
34
+
35
+ {#if isVisible}
36
+ <div
37
+ class="fixed top-4 right-4 max-w-sm w-full bg-white border rounded-lg shadow-lg p-4 z-50"
38
+ role="alert"
39
+ {...restProps}
40
+ >
41
+ <div class="flex items-start">
42
+ <div class="flex-1">
43
+ <p class="text-sm {typeClasses[type]}">{message}</p>
44
+ </div>
45
+
46
+ {#if closable}
47
+ <button
48
+ type="button"
49
+ class="ml-3 text-gray-400 hover:text-gray-600"
50
+ onclick={closeToast}
51
+ aria-label="Close notification"
52
+ >
53
+ ×
54
+ </button>
55
+ {/if}
56
+ </div>
57
+ </div>
58
+ {/if}
@@ -0,0 +1,9 @@
1
+ interface Props {
2
+ message?: string;
3
+ type?: "success" | "error" | "warning" | "info";
4
+ closable?: boolean;
5
+ onclick?: (event: Event) => void;
6
+ }
7
+ declare const Toast: import("svelte").Component<Props, {}, "">;
8
+ type Toast = ReturnType<typeof Toast>;
9
+ export default Toast;
@@ -0,0 +1,94 @@
1
+ <script lang="ts">
2
+ // SSR-safe ID generation
3
+ function generateId(prefix: string = "id"): string {
4
+ if (typeof window !== "undefined") {
5
+ return `${prefix}-${Math.random().toString(36).substr(2, 9)}`;
6
+ } else {
7
+ return `${prefix}-ssr-${Date.now()}`;
8
+ }
9
+ }
10
+
11
+ // Props using Svelte 5 runes
12
+ interface Props {
13
+ checked?: boolean;
14
+ disabled?: boolean;
15
+ label?: string;
16
+ onclick?: (event: MouseEvent) => void;
17
+ onchange?: (event: { checked: boolean }) => void;
18
+ }
19
+
20
+ let {
21
+ checked = false,
22
+ disabled = false,
23
+ label = "",
24
+ onclick,
25
+ onchange,
26
+ ...restProps
27
+ }: Props = $props();
28
+
29
+ // SSR-safe ID generation (call directly, not in onMount)
30
+ const toggleId = generateId("toggle");
31
+
32
+ // Handle click
33
+ function handleClick(event: MouseEvent) {
34
+ if (disabled) return;
35
+ checked = !checked;
36
+
37
+ // Call parent handlers if provided
38
+ if (onclick) onclick(event);
39
+ if (onchange) onchange({ checked });
40
+ }
41
+
42
+ // Toggle button classes using full class names
43
+ const toggleButtonClasses = $derived(() => {
44
+ const baseClasses =
45
+ "relative inline-flex w-11 h-6 flex-shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2";
46
+ const stateClasses = checked ? "bg-blue-600" : "bg-gray-200";
47
+ const disabledClasses = disabled ? "opacity-50 cursor-not-allowed" : "";
48
+
49
+ return `${baseClasses} ${stateClasses} ${disabledClasses}`.trim();
50
+ });
51
+
52
+ // Toggle thumb classes using full class names
53
+ const toggleThumbClasses = $derived(() => {
54
+ const baseClasses =
55
+ "pointer-events-none inline-block w-5 h-5 transform rounded-full bg-white shadow-lg transition duration-200 ease-in-out";
56
+ const positionClasses = checked ? "translate-x-5" : "translate-x-0";
57
+
58
+ return `${baseClasses} ${positionClasses}`.trim();
59
+ });
60
+
61
+ // Handle keyboard
62
+ function handleKeydown(event: KeyboardEvent) {
63
+ if (disabled) return;
64
+ if (event.key === " " || event.key === "Enter") {
65
+ event.preventDefault();
66
+ handleClick(event as any);
67
+ }
68
+ }
69
+ </script>
70
+
71
+ <div class="flex items-center gap-3">
72
+ <button
73
+ type="button"
74
+ role="switch"
75
+ id={toggleId}
76
+ aria-checked={checked}
77
+ aria-label={label || "Toggle"}
78
+ {disabled}
79
+ onclick={handleClick}
80
+ onkeydown={handleKeydown}
81
+ class={toggleButtonClasses()}
82
+ >
83
+ <span class={toggleThumbClasses()}></span>
84
+ </button>
85
+
86
+ {#if label}
87
+ <label
88
+ for={toggleId}
89
+ class="text-sm font-medium text-label cursor-pointer"
90
+ >
91
+ {label}
92
+ </label>
93
+ {/if}
94
+ </div>
@@ -0,0 +1,12 @@
1
+ interface Props {
2
+ checked?: boolean;
3
+ disabled?: boolean;
4
+ label?: string;
5
+ onclick?: (event: MouseEvent) => void;
6
+ onchange?: (event: {
7
+ checked: boolean;
8
+ }) => void;
9
+ }
10
+ declare const Toggle: import("svelte").Component<Props, {}, "">;
11
+ type Toggle = ReturnType<typeof Toggle>;
12
+ export default Toggle;
@@ -0,0 +1,188 @@
1
+ <script lang="ts">
2
+ interface Props {
3
+ content?: string;
4
+ placement?: "top" | "bottom" | "left" | "right";
5
+ delay?: number;
6
+ disabled?: boolean;
7
+ }
8
+
9
+ let {
10
+ content = "",
11
+ placement = "top",
12
+ delay = 0,
13
+ disabled = false,
14
+ children,
15
+ ...restProps
16
+ }: Props & { children?: any } = $props();
17
+ </script>
18
+
19
+ <div
20
+ class="tooltip-container group relative inline-block"
21
+ data-placement={placement}
22
+ data-delay={delay}
23
+ data-disabled={disabled}
24
+ {...restProps}
25
+ >
26
+ {@render children?.()}
27
+
28
+ {#if content && !disabled}
29
+ <div
30
+ class="tooltip group-hover:opacity-100 group-hover:visible group-focus-within:opacity-100 group-focus-within:visible"
31
+ role="tooltip"
32
+ aria-hidden="true"
33
+ >
34
+ {content}
35
+ </div>
36
+ {/if}
37
+ </div>
38
+
39
+ <style>
40
+ :root {
41
+ --tooltip-bg: #1f2937;
42
+ --tooltip-color: white;
43
+ --tooltip-padding: 0.5rem 0.75rem;
44
+ --tooltip-radius: 0.375rem;
45
+ --tooltip-font-size: 0.875rem;
46
+ --tooltip-line-height: 1.25rem;
47
+ --tooltip-max-width: 200px;
48
+ --tooltip-gap: 0.5rem;
49
+ --tooltip-arrow-size: 4px;
50
+ --tooltip-transition: opacity 0.2s ease-in-out,
51
+ visibility 0.2s ease-in-out;
52
+ }
53
+
54
+ .tooltip-container {
55
+ position: relative;
56
+ display: inline-block;
57
+ }
58
+
59
+ .tooltip {
60
+ position: absolute;
61
+ z-index: 50;
62
+ padding: var(--tooltip-padding);
63
+ background-color: var(--tooltip-bg);
64
+ color: var(--tooltip-color);
65
+ border-radius: var(--tooltip-radius);
66
+ font-size: var(--tooltip-font-size);
67
+ line-height: var(--tooltip-line-height);
68
+ max-width: var(--tooltip-max-width);
69
+ white-space: normal;
70
+ word-wrap: break-word;
71
+ opacity: 0;
72
+ visibility: hidden;
73
+ transition: var(--tooltip-transition);
74
+ pointer-events: none;
75
+ /* Use logical properties for better internationalization */
76
+ inset-inline-start: 50%;
77
+ inset-block-start: 50%;
78
+ transform: translate(-50%, -50%);
79
+ }
80
+
81
+ /* Simplified positioning using CSS custom properties and logical properties */
82
+ .tooltip-container[data-placement="top"] .tooltip {
83
+ inset-block-end: 100%;
84
+ inset-inline-start: 50%;
85
+ transform: translateX(-50%);
86
+ margin-block-end: var(--tooltip-gap);
87
+ }
88
+
89
+ .tooltip-container[data-placement="bottom"] .tooltip {
90
+ inset-block-start: 100%;
91
+ inset-inline-start: 50%;
92
+ transform: translateX(-50%);
93
+ margin-block-start: var(--tooltip-gap);
94
+ }
95
+
96
+ .tooltip-container[data-placement="left"] .tooltip {
97
+ inset-inline-end: 100%;
98
+ inset-block-start: 50%;
99
+ transform: translateY(-50%);
100
+ margin-inline-end: var(--tooltip-gap);
101
+ }
102
+
103
+ .tooltip-container[data-placement="right"] .tooltip {
104
+ inset-inline-start: 100%;
105
+ inset-block-start: 50%;
106
+ transform: translateY(-50%);
107
+ margin-inline-start: var(--tooltip-gap);
108
+ }
109
+
110
+ /* Modern arrow implementation using CSS clip-path for better performance */
111
+ .tooltip::before {
112
+ content: "";
113
+ position: absolute;
114
+ width: calc(var(--tooltip-arrow-size) * 2);
115
+ height: calc(var(--tooltip-arrow-size) * 2);
116
+ background-color: var(--tooltip-bg);
117
+ }
118
+
119
+ .tooltip-container[data-placement="top"] .tooltip::before {
120
+ inset-block-start: 100%;
121
+ inset-inline-start: 50%;
122
+ transform: translateX(-50%);
123
+ clip-path: polygon(50% 100%, 0 0, 100% 0);
124
+ }
125
+
126
+ .tooltip-container[data-placement="bottom"] .tooltip::before {
127
+ inset-block-end: 100%;
128
+ inset-inline-start: 50%;
129
+ transform: translateX(-50%);
130
+ clip-path: polygon(0 100%, 50% 0, 100% 100%);
131
+ }
132
+
133
+ .tooltip-container[data-placement="left"] .tooltip::before {
134
+ inset-inline-start: 100%;
135
+ inset-block-start: 50%;
136
+ transform: translateY(-50%);
137
+ clip-path: polygon(0 50%, 100% 0, 100% 100%);
138
+ }
139
+
140
+ .tooltip-container[data-placement="right"] .tooltip::before {
141
+ inset-inline-end: 100%;
142
+ inset-block-start: 50%;
143
+ transform: translateY(-50%);
144
+ clip-path: polygon(0 0, 100% 50%, 0 100%);
145
+ }
146
+
147
+ /* Delay support using CSS custom properties */
148
+ .tooltip-container[data-delay] .tooltip {
149
+ transition-delay: calc(var(--tooltip-delay, 0) * 1ms);
150
+ }
151
+
152
+ /* Responsive design with modern CSS */
153
+ @media (max-width: 640px) {
154
+ .tooltip {
155
+ --tooltip-max-width: calc(100vw - 2rem);
156
+ inset-inline-start: 50% !important;
157
+ inset-inline-end: auto !important;
158
+ transform: translateX(-50%) !important;
159
+ margin: var(--tooltip-gap) 0 !important;
160
+ }
161
+
162
+ .tooltip::before {
163
+ display: none;
164
+ }
165
+ }
166
+
167
+ /* Dark mode support */
168
+ @media (prefers-color-scheme: dark) {
169
+ :root {
170
+ --tooltip-bg: #374151;
171
+ }
172
+ }
173
+
174
+ /* High contrast mode support */
175
+ @media (prefers-contrast: high) {
176
+ :root {
177
+ --tooltip-bg: #000000;
178
+ --tooltip-color: #ffffff;
179
+ }
180
+ }
181
+
182
+ /* Reduced motion support */
183
+ @media (prefers-reduced-motion: reduce) {
184
+ .tooltip {
185
+ transition: none;
186
+ }
187
+ }
188
+ </style>
@@ -0,0 +1,12 @@
1
+ interface Props {
2
+ content?: string;
3
+ placement?: "top" | "bottom" | "left" | "right";
4
+ delay?: number;
5
+ disabled?: boolean;
6
+ }
7
+ type $$ComponentProps = Props & {
8
+ children?: any;
9
+ };
10
+ declare const Tooltip: import("svelte").Component<$$ComponentProps, {}, "">;
11
+ type Tooltip = ReturnType<typeof Tooltip>;
12
+ export default Tooltip;
@@ -1,20 +1,9 @@
1
- // Atomic Components - Basic building blocks
1
+ export { default as Toggle } from './Toggle.svelte';
2
2
  export { default as Badge } from './Badge.svelte';
3
3
  export { default as Button } from './Button.svelte';
4
4
  export { default as Card } from './Card.svelte';
5
- export { default as Checkbox } from './Checkbox.svelte';
6
- export { default as ColorPicker } from './ColorPicker.svelte';
7
- export { default as Heading } from './Heading.svelte';
8
5
  export { default as Input } from './Input.svelte';
9
- export { default as OptimizedImage } from './OptimizedImage.svelte';
10
- export { default as DebugPanel } from './PerformanceMonitor.svelte';
11
- export { default as Progress } from './Progress.svelte';
12
- export { default as ScaleDemo } from './ScaleDemo.svelte';
13
- export { default as Select } from './Select.svelte';
14
- export { default as Skeleton } from './Skeleton.svelte';
15
6
  export { default as Textarea } from './Textarea.svelte';
16
- export { default as TextAlignment } from './TextAlignment.svelte';
17
- export { default as ThemeToggle } from './ThemeToggle.svelte';
18
- export { default as Toast } from './Toast.svelte';
19
- export { default as Toggle } from './Toggle.svelte';
20
- export { default as Tooltip } from './Tooltip.svelte';
7
+ export { default as Select } from './Select.svelte';
8
+ export { default as ColorPicker } from './ColorPicker.svelte';
9
+ export { default as Heading } from './Heading.svelte';