twintrinsic 0.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 (212) hide show
  1. package/LICENSE +674 -0
  2. package/README.md +150 -0
  3. package/dist/App/App.svelte +54 -0
  4. package/dist/App/App.svelte.d.ts +65 -0
  5. package/dist/Section.svelte +25 -0
  6. package/dist/Section.svelte.d.ts +34 -0
  7. package/dist/actions/clickOutside.d.ts +9 -0
  8. package/dist/actions/clickOutside.js +19 -0
  9. package/dist/actions/index.d.ts +1 -0
  10. package/dist/actions/index.js +1 -0
  11. package/dist/components/Accordion/Accordion.svelte +75 -0
  12. package/dist/components/Accordion/Accordion.svelte.d.ts +39 -0
  13. package/dist/components/Accordion/AccordionItem.svelte +150 -0
  14. package/dist/components/Accordion/AccordionItem.svelte.d.ts +30 -0
  15. package/dist/components/App/App.story.md +8 -0
  16. package/dist/components/App/App.story.svelte +170 -0
  17. package/dist/components/App/App.story.svelte.d.ts +22 -0
  18. package/dist/components/App/App.svelte +77 -0
  19. package/dist/components/App/App.svelte.d.ts +66 -0
  20. package/dist/components/App/Split.svelte +346 -0
  21. package/dist/components/App/Split.svelte.d.ts +54 -0
  22. package/dist/components/App/index.d.ts +2 -0
  23. package/dist/components/App/index.js +3 -0
  24. package/dist/components/AppHeader/AppHeader.svelte +439 -0
  25. package/dist/components/AppHeader/AppHeader.svelte.d.ts +24 -0
  26. package/dist/components/Avatar/Avatar.svelte +300 -0
  27. package/dist/components/Avatar/Avatar.svelte.d.ts +48 -0
  28. package/dist/components/Avatar/AvatarGroup.svelte +185 -0
  29. package/dist/components/Avatar/AvatarGroup.svelte.d.ts +46 -0
  30. package/dist/components/Badge/Badge.svelte +186 -0
  31. package/dist/components/Badge/Badge.svelte.d.ts +51 -0
  32. package/dist/components/BottomBar/BottomBar.svelte +146 -0
  33. package/dist/components/BottomBar/BottomBar.svelte.d.ts +38 -0
  34. package/dist/components/Breadcrumb/Breadcrumb.svelte +77 -0
  35. package/dist/components/Breadcrumb/Breadcrumb.svelte.d.ts +42 -0
  36. package/dist/components/Breadcrumb/BreadcrumbItem.svelte +171 -0
  37. package/dist/components/Breadcrumb/BreadcrumbItem.svelte.d.ts +38 -0
  38. package/dist/components/Button/Button.svelte +252 -0
  39. package/dist/components/Button/Button.svelte.d.ts +80 -0
  40. package/dist/components/Button/ButtonGroup.svelte +127 -0
  41. package/dist/components/Button/ButtonGroup.svelte.d.ts +44 -0
  42. package/dist/components/Card/Card.svelte +152 -0
  43. package/dist/components/Card/Card.svelte.d.ts +55 -0
  44. package/dist/components/Carousel/Carousel.svelte +461 -0
  45. package/dist/components/Carousel/Carousel.svelte.d.ts +79 -0
  46. package/dist/components/Carousel/CarouselItem.svelte +149 -0
  47. package/dist/components/Carousel/CarouselItem.svelte.d.ts +35 -0
  48. package/dist/components/Chip/Chip.svelte +288 -0
  49. package/dist/components/Chip/Chip.svelte.d.ts +71 -0
  50. package/dist/components/Chip/ChipGroup.svelte +190 -0
  51. package/dist/components/Chip/ChipGroup.svelte.d.ts +71 -0
  52. package/dist/components/CodeBlock/CodeBlock.svelte +356 -0
  53. package/dist/components/CodeBlock/CodeBlock.svelte.d.ts +44 -0
  54. package/dist/components/CodeBlock/index.d.ts +1 -0
  55. package/dist/components/CodeBlock/index.js +1 -0
  56. package/dist/components/CodeBlockSpeed/CodeBlockSpeed.svelte +145 -0
  57. package/dist/components/CodeBlockSpeed/CodeBlockSpeed.svelte.d.ts +44 -0
  58. package/dist/components/CodeEditor/CodeEditor.svelte +229 -0
  59. package/dist/components/CodeEditor/CodeEditor.svelte.d.ts +23 -0
  60. package/dist/components/Combobox/Combobox.svelte +279 -0
  61. package/dist/components/Combobox/Combobox.svelte.d.ts +34 -0
  62. package/dist/components/Container/Container.svelte +45 -0
  63. package/dist/components/Container/Container.svelte.d.ts +36 -0
  64. package/dist/components/DataTable/DataTable.svelte +879 -0
  65. package/dist/components/DataTable/DataTable.svelte.d.ts +102 -0
  66. package/dist/components/Form/AutoComplete.svelte +357 -0
  67. package/dist/components/Form/AutoComplete.svelte.d.ts +73 -0
  68. package/dist/components/Form/Calendar.svelte +429 -0
  69. package/dist/components/Form/Calendar.svelte.d.ts +53 -0
  70. package/dist/components/Form/Checkbox.svelte +196 -0
  71. package/dist/components/Form/Checkbox.svelte.d.ts +50 -0
  72. package/dist/components/Form/ColorPicker.svelte +396 -0
  73. package/dist/components/Form/ColorPicker.svelte.d.ts +43 -0
  74. package/dist/components/Form/Combobox.svelte +645 -0
  75. package/dist/components/Form/Combobox.svelte.d.ts +93 -0
  76. package/dist/components/Form/Dropdown.svelte +773 -0
  77. package/dist/components/Form/Dropdown.svelte.d.ts +81 -0
  78. package/dist/components/Form/FileUpload.svelte +796 -0
  79. package/dist/components/Form/FileUpload.svelte.d.ts +78 -0
  80. package/dist/components/Form/FloatLabel.svelte +245 -0
  81. package/dist/components/Form/FloatLabel.svelte.d.ts +44 -0
  82. package/dist/components/Form/Form.svelte +281 -0
  83. package/dist/components/Form/Form.svelte.d.ts +54 -0
  84. package/dist/components/Form/FormField.svelte +218 -0
  85. package/dist/components/Form/FormField.svelte.d.ts +47 -0
  86. package/dist/components/Form/Input.svelte +340 -0
  87. package/dist/components/Form/Input.svelte.d.ts +79 -0
  88. package/dist/components/Form/InputSwitch.svelte +189 -0
  89. package/dist/components/Form/InputSwitch.svelte.d.ts +46 -0
  90. package/dist/components/Form/InvalidState.svelte +97 -0
  91. package/dist/components/Form/InvalidState.svelte.d.ts +37 -0
  92. package/dist/components/Form/Knob.svelte +537 -0
  93. package/dist/components/Form/Knob.svelte.d.ts +78 -0
  94. package/dist/components/Form/ListInput.svelte +469 -0
  95. package/dist/components/Form/ListInput.svelte.d.ts +70 -0
  96. package/dist/components/Form/Listbox.svelte +513 -0
  97. package/dist/components/Form/Listbox.svelte.d.ts +74 -0
  98. package/dist/components/Form/NumberInput.svelte +452 -0
  99. package/dist/components/Form/NumberInput.svelte.d.ts +82 -0
  100. package/dist/components/Form/Radio.svelte +192 -0
  101. package/dist/components/Form/Radio.svelte.d.ts +53 -0
  102. package/dist/components/Form/RadioGroup.svelte +155 -0
  103. package/dist/components/Form/RadioGroup.svelte.d.ts +48 -0
  104. package/dist/components/Form/Rating.svelte +380 -0
  105. package/dist/components/Form/Rating.svelte.d.ts +64 -0
  106. package/dist/components/Form/Select.svelte +436 -0
  107. package/dist/components/Form/Select.svelte.d.ts +49 -0
  108. package/dist/components/Form/SelectGroup.svelte +34 -0
  109. package/dist/components/Form/SelectGroup.svelte.d.ts +33 -0
  110. package/dist/components/Form/Slider.svelte +622 -0
  111. package/dist/components/Form/Slider.svelte.d.ts +73 -0
  112. package/dist/components/Form/Switch.svelte +192 -0
  113. package/dist/components/Form/Switch.svelte.d.ts +46 -0
  114. package/dist/components/Form/TextInput.svelte +274 -0
  115. package/dist/components/Form/TextInput.svelte.d.ts +74 -0
  116. package/dist/components/Form/Textarea.svelte +207 -0
  117. package/dist/components/Form/Textarea.svelte.d.ts +62 -0
  118. package/dist/components/Icon/Icon.svelte +140 -0
  119. package/dist/components/Icon/Icon.svelte.d.ts +25 -0
  120. package/dist/components/Icon/index.d.ts +1 -0
  121. package/dist/components/Icon/index.js +1 -0
  122. package/dist/components/Lazy/Lazy.svelte +158 -0
  123. package/dist/components/Lazy/Lazy.svelte.d.ts +42 -0
  124. package/dist/components/Masonry/Masonry.svelte +299 -0
  125. package/dist/components/Masonry/Masonry.svelte.d.ts +55 -0
  126. package/dist/components/Menu/Menu/Menu.svelte +65 -0
  127. package/dist/components/Menu/Menu/Menu.svelte.d.ts +17 -0
  128. package/dist/components/Menu/Menu/MenuItem.svelte +90 -0
  129. package/dist/components/Menu/Menu/MenuItem.svelte.d.ts +27 -0
  130. package/dist/components/Modal/Modal.svelte +334 -0
  131. package/dist/components/Modal/Modal.svelte.d.ts +55 -0
  132. package/dist/components/Panel/Card.svelte +141 -0
  133. package/dist/components/Panel/Card.svelte.d.ts +52 -0
  134. package/dist/components/Panel/Hero/Hero.story.md +9 -0
  135. package/dist/components/Panel/Hero/Hero.story.svelte +49 -0
  136. package/dist/components/Panel/Hero/Hero.story.svelte.d.ts +21 -0
  137. package/dist/components/Panel/Hero/Hero.svelte +24 -0
  138. package/dist/components/Panel/Hero/Hero.svelte.d.ts +32 -0
  139. package/dist/components/Panel/LazyPanel.svelte +110 -0
  140. package/dist/components/Panel/LazyPanel.svelte.d.ts +46 -0
  141. package/dist/components/Panel/Panel.svelte +205 -0
  142. package/dist/components/Panel/Panel.svelte.d.ts +23 -0
  143. package/dist/components/Progress/Progress.svelte +220 -0
  144. package/dist/components/Progress/Progress.svelte.d.ts +61 -0
  145. package/dist/components/Separator/Separator.svelte +109 -0
  146. package/dist/components/Separator/Separator.svelte.d.ts +35 -0
  147. package/dist/components/Sidebar/Sidebar.svelte +213 -0
  148. package/dist/components/Sidebar/Sidebar.svelte.d.ts +60 -0
  149. package/dist/components/Skeleton/Skeleton.svelte +170 -0
  150. package/dist/components/Skeleton/Skeleton.svelte.d.ts +48 -0
  151. package/dist/components/Stepper/Stepper.svelte +111 -0
  152. package/dist/components/Stepper/Stepper.svelte.d.ts +54 -0
  153. package/dist/components/Stepper/StepperStep.svelte +369 -0
  154. package/dist/components/Stepper/StepperStep.svelte.d.ts +63 -0
  155. package/dist/components/Table/Table.svelte +167 -0
  156. package/dist/components/Table/Table.svelte.d.ts +56 -0
  157. package/dist/components/Table/TableBody.svelte +41 -0
  158. package/dist/components/Table/TableBody.svelte.d.ts +33 -0
  159. package/dist/components/Table/TableCell.svelte +76 -0
  160. package/dist/components/Table/TableCell.svelte.d.ts +36 -0
  161. package/dist/components/Table/TableHead.svelte +41 -0
  162. package/dist/components/Table/TableHead.svelte.d.ts +32 -0
  163. package/dist/components/Table/TableHeader.svelte +148 -0
  164. package/dist/components/Table/TableHeader.svelte.d.ts +42 -0
  165. package/dist/components/Table/TableRow.svelte +99 -0
  166. package/dist/components/Table/TableRow.svelte.d.ts +40 -0
  167. package/dist/components/Tabs/Tab.svelte +145 -0
  168. package/dist/components/Tabs/Tab.svelte.d.ts +36 -0
  169. package/dist/components/Tabs/TabList.svelte +60 -0
  170. package/dist/components/Tabs/TabList.svelte.d.ts +32 -0
  171. package/dist/components/Tabs/TabPanel.svelte +118 -0
  172. package/dist/components/Tabs/TabPanel.svelte.d.ts +38 -0
  173. package/dist/components/Tabs/Tabs.svelte +287 -0
  174. package/dist/components/Tabs/Tabs.svelte.d.ts +50 -0
  175. package/dist/components/Tag/Tag.svelte +260 -0
  176. package/dist/components/Tag/Tag.svelte.d.ts +54 -0
  177. package/dist/components/Tag/TagGroup.svelte +147 -0
  178. package/dist/components/Tag/TagGroup.svelte.d.ts +62 -0
  179. package/dist/components/ThemeToggle/ThemeToggle.svelte +93 -0
  180. package/dist/components/ThemeToggle/ThemeToggle.svelte.d.ts +12 -0
  181. package/dist/components/Timeline/Timeline.svelte +144 -0
  182. package/dist/components/Timeline/Timeline.svelte.d.ts +48 -0
  183. package/dist/components/Timeline/TimelineItem.svelte +391 -0
  184. package/dist/components/Timeline/TimelineItem.svelte.d.ts +63 -0
  185. package/dist/components/Toast/Toast.svelte +313 -0
  186. package/dist/components/Toast/Toast.svelte.d.ts +44 -0
  187. package/dist/components/Toast/toastStore.d.ts +40 -0
  188. package/dist/components/Toast/toastStore.js +293 -0
  189. package/dist/components/Tooltip/Tooltip.svelte +282 -0
  190. package/dist/components/Tooltip/Tooltip.svelte.d.ts +55 -0
  191. package/dist/components/Tree/Tree.svelte +129 -0
  192. package/dist/components/Tree/Tree.svelte.d.ts +61 -0
  193. package/dist/components/Tree/TreeNode.svelte +332 -0
  194. package/dist/components/Tree/TreeNode.svelte.d.ts +55 -0
  195. package/dist/components/icons/TwintrinsicLogo.svelte +73 -0
  196. package/dist/components/icons/TwintrinsicLogo.svelte.d.ts +17 -0
  197. package/dist/components/icons/twintrinsic-source.svg +73 -0
  198. package/dist/components/icons/twintrinsic.svg +38 -0
  199. package/dist/docs/EventsTable.svelte +86 -0
  200. package/dist/docs/EventsTable.svelte.d.ts +27 -0
  201. package/dist/docs/PropsTable.svelte +103 -0
  202. package/dist/docs/PropsTable.svelte.d.ts +28 -0
  203. package/dist/docs/index.d.ts +2 -0
  204. package/dist/docs/index.js +2 -0
  205. package/dist/helpers/detectLanguage.d.ts +6 -0
  206. package/dist/helpers/detectLanguage.js +60 -0
  207. package/dist/helpers/index.d.ts +1 -0
  208. package/dist/helpers/index.js +1 -0
  209. package/dist/index.d.ts +86 -0
  210. package/dist/index.js +94 -0
  211. package/dist/twintrinsic.css +347 -0
  212. package/package.json +98 -0
@@ -0,0 +1,300 @@
1
+ <!--
2
+ @component
3
+ Avatar - A component for displaying user profile images with fallback options.
4
+ Provides consistent styling, accessibility features, and various display options.
5
+
6
+ Usage:
7
+ ```svelte
8
+ <Avatar
9
+ src="/path/to/image.jpg"
10
+ alt="User Name"
11
+ />
12
+
13
+ <Avatar
14
+ name="John Doe"
15
+ size="lg"
16
+ shape="square"
17
+ />
18
+
19
+ <Avatar
20
+ gravatarEmail="user@example.com"
21
+ name="John Doe"
22
+ status="online"
23
+ />
24
+
25
+ <Avatar
26
+ src="/path/to/image.jpg"
27
+ fallback="JD"
28
+ status="online"
29
+ />
30
+ ```
31
+ -->
32
+ <script lang="ts">
33
+ import { onMount } from "svelte"
34
+
35
+ const {
36
+ /** @type {string} - Additional CSS classes */
37
+ class: className = "",
38
+
39
+ /** @type {string} - HTML id for accessibility */
40
+ id = crypto.randomUUID(),
41
+
42
+ /** @type {string} - Image source URL */
43
+ src,
44
+
45
+ /** @type {string} - Alt text for the image */
46
+ alt,
47
+
48
+ /** @type {string} - User name for generating initials */
49
+ name,
50
+
51
+ /** @type {string} - Fallback text when image fails to load or no src provided */
52
+ fallback,
53
+
54
+ /** @type {string} - Gravatar email address */
55
+ gravatarEmail,
56
+
57
+ /** @type {string} - Size of the avatar (xs, sm, md, lg, xl) */
58
+ size = "md",
59
+
60
+ /** @type {string} - Shape of the avatar (circle, square, rounded) */
61
+ shape = "circle",
62
+
63
+ /** @type {"online" | "offline" | "away" | "busy" | undefined} - Status indicator (online, offline, away, busy) */
64
+ status,
65
+
66
+ /** @type {string} - Background color for text avatars (CSS color value) */
67
+ bgColor,
68
+
69
+ /** @type {boolean} - Whether to show a border */
70
+ bordered = false,
71
+
72
+ /** @type {boolean} - Whether to add a shadow effect */
73
+ shadowed = false,
74
+
75
+ /** @type {Function} - Custom function to generate initials */
76
+ initialsGenerator,
77
+ } = $props()
78
+
79
+ // Component state
80
+ let imageLoaded = $state(false)
81
+ let imageError = $state(false)
82
+ let avatarElement
83
+ let gravatarUrl = $state("")
84
+
85
+ // Generate gravatar URL if email is provided
86
+ $effect(() => {
87
+ if (gravatarEmail) {
88
+ generateGravatarUrl(gravatarEmail).then(url => {
89
+ gravatarUrl = url
90
+ })
91
+ }
92
+ })
93
+
94
+ /**
95
+ * Generates a Gravatar URL from an email address using MD5 hash
96
+ * @param {string} email - Email address
97
+ * @returns {Promise<string>} - Gravatar URL
98
+ */
99
+ async function generateGravatarUrl(email: string): Promise<string> {
100
+ if (!email) return ""
101
+
102
+ const trimmedEmail = email.trim().toLowerCase()
103
+ const msgBuffer = new TextEncoder().encode(trimmedEmail)
104
+ const hashBuffer = await crypto.subtle.digest("SHA-256", msgBuffer)
105
+ const hashArray = Array.from(new Uint8Array(hashBuffer))
106
+ const hashHex = hashArray.map(b => b.toString(16).padStart(2, "0")).join("")
107
+
108
+ return `https://www.gravatar.com/avatar/${hashHex}?d=identicon`
109
+ }
110
+
111
+ /**
112
+ * Generates initials from a name
113
+ * @param {string} name - Full name
114
+ * @returns {string} - Initials (1-2 characters)
115
+ */
116
+ function generateInitials(name: string): string {
117
+ if (!name) return ""
118
+
119
+ if (initialsGenerator) {
120
+ return initialsGenerator(name)
121
+ }
122
+
123
+ // Default implementation: first letter of first and last name
124
+ const parts = name.trim().split(/\s+/)
125
+
126
+ if (parts.length === 1) {
127
+ return parts[0].charAt(0).toUpperCase()
128
+ }
129
+
130
+ return (parts[0].charAt(0) + parts[parts.length - 1].charAt(0)).toUpperCase()
131
+ }
132
+
133
+ /**
134
+ * Handles image load event
135
+ */
136
+ function handleImageLoad() {
137
+ imageLoaded = true
138
+ imageError = false
139
+ }
140
+
141
+ /**
142
+ * Handles image error event
143
+ */
144
+ function handleImageError() {
145
+ imageLoaded = false
146
+ imageError = true
147
+ }
148
+
149
+ // Determine what to display as fallback
150
+ const displayFallback = $derived(fallback || (name ? generateInitials(name) : ""))
151
+
152
+ // Determine the image source (prefer explicit src over gravatar)
153
+ const imageSrc = $derived(src || gravatarUrl)
154
+
155
+ // Determine if we should show the image
156
+ const showImage = $derived(imageSrc && !imageError)
157
+
158
+ // Determine if we should show the fallback
159
+ const showFallback = $derived(!showImage && !!displayFallback)
160
+
161
+ // Determine size classes
162
+ const sizeClasses = $derived(
163
+ {
164
+ xs: "w-6 h-6 text-xs",
165
+ sm: "w-8 h-8 text-sm",
166
+ md: "w-10 h-10 text-base",
167
+ lg: "w-12 h-12 text-lg",
168
+ xl: "w-16 h-16 text-xl",
169
+ }[size] || "w-10 h-10 text-base"
170
+ )
171
+
172
+ // Determine shape classes
173
+ const shapeClasses = $derived(
174
+ {
175
+ circle: "rounded-full",
176
+ square: "rounded-none",
177
+ rounded: "rounded-md",
178
+ }[shape] || "rounded-full"
179
+ )
180
+
181
+ // Determine status classes
182
+ const statusClasses = $derived.by(() => {
183
+ if (status === "online") return "bg-success-500"
184
+ if (status === "offline") return "bg-muted"
185
+ if (status === "away") return "bg-warning-500"
186
+ if (status === "busy") return "bg-error-500"
187
+ return "bg-muted"
188
+ })
189
+
190
+ // Generate a random color based on the name or fallback
191
+ const randomBgColor = $derived(generateRandomColor())
192
+
193
+ // Function to generate a random color based on the name or fallback
194
+ function generateRandomColor() {
195
+ if (bgColor) return bgColor
196
+
197
+ const seed = name || fallback || id
198
+ const colors = [
199
+ "bg-primary-500",
200
+ "bg-secondary-500",
201
+ "bg-success-500",
202
+ "bg-warning-500",
203
+ "bg-error-500",
204
+ "bg-info-500",
205
+ ]
206
+
207
+ // Simple hash function to get consistent color
208
+ let hash = 0
209
+ for (let i = 0; i < seed.length; i++) {
210
+ hash = (hash << 5) - hash + seed.charCodeAt(i)
211
+ hash = hash & hash // Convert to 32bit integer
212
+ }
213
+
214
+ const index = Math.abs(hash) % colors.length
215
+ return colors[index]
216
+ }
217
+ </script>
218
+
219
+ <div
220
+ {id}
221
+ class="
222
+ avatar
223
+ {sizeClasses}
224
+ {shapeClasses}
225
+ {bordered ? 'avatar-bordered' : ''}
226
+ {shadowed ? 'avatar-shadowed' : ''}
227
+ {className}
228
+ "
229
+ aria-label={alt || name || 'Avatar'}
230
+ bind:this={avatarElement}
231
+ >
232
+ {#if showImage}
233
+ <img
234
+ src={imageSrc}
235
+ alt={alt || name || 'Avatar'}
236
+ class="avatar-image"
237
+ onload={handleImageLoad}
238
+ onerror={handleImageError}
239
+ />
240
+ {:else if showFallback}
241
+ <div
242
+ class="avatar-fallback {randomBgColor}"
243
+ style={bgColor ? `background-color: ${bgColor}` : ''}
244
+ >
245
+ {displayFallback}
246
+ </div>
247
+ {:else}
248
+ <div class="avatar-placeholder">
249
+ <svg class="w-full h-full" fill="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
250
+ <path d="M12 12a5 5 0 100-10 5 5 0 000 10zm0-2a3 3 0 100-6 3 3 0 000 6zm9 11a1 1 0 01-1 1H4a1 1 0 01-1-1v-1c0-3.87 3.13-7 7-7h4c3.87 0 7 3.13 7 7v1z"/>
251
+ </svg>
252
+ </div>
253
+ {/if}
254
+
255
+ {#if status}
256
+ <span
257
+ class="avatar-status {statusClasses}"
258
+ aria-label={`Status: ${status}`}
259
+ ></span>
260
+ {/if}
261
+ </div>
262
+
263
+ <style>
264
+ @reference "../../twintrinsic.css";
265
+
266
+ .avatar {
267
+ @apply relative inline-flex items-center justify-center flex-shrink-0;
268
+ @apply bg-surface dark:bg-surface text-text dark:text-text;
269
+ @apply overflow-hidden;
270
+ }
271
+
272
+ .avatar-bordered {
273
+ @apply border-2 border-background dark:border-background;
274
+ }
275
+
276
+ .avatar-shadowed {
277
+ @apply shadow-md dark:shadow-lg;
278
+ }
279
+
280
+ .avatar-image {
281
+ @apply w-full h-full object-cover;
282
+ }
283
+
284
+ .avatar-fallback {
285
+ @apply w-full h-full flex items-center justify-center;
286
+ @apply text-white dark:text-white font-medium;
287
+ }
288
+
289
+ .avatar-placeholder {
290
+ @apply w-full h-full flex items-center justify-center;
291
+ @apply bg-muted/20 dark:bg-muted/20 text-muted dark:text-muted;
292
+ }
293
+
294
+ .avatar-status {
295
+ @apply absolute bottom-0 right-0;
296
+ @apply w-1/4 h-1/4 min-w-1.5 min-h-1.5 max-w-3 max-h-3;
297
+ @apply rounded-full;
298
+ @apply border-2 border-background dark:border-background;
299
+ }
300
+ </style>
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Avatar - A component for displaying user profile images with fallback options.
3
+ * Provides consistent styling, accessibility features, and various display options.
4
+ *
5
+ * Usage:
6
+ * ```svelte
7
+ * <Avatar
8
+ * src="/path/to/image.jpg"
9
+ * alt="User Name"
10
+ * />
11
+ *
12
+ * <Avatar
13
+ * name="John Doe"
14
+ * size="lg"
15
+ * shape="square"
16
+ * />
17
+ *
18
+ * <Avatar
19
+ * gravatarEmail="user@example.com"
20
+ * name="John Doe"
21
+ * status="online"
22
+ * />
23
+ *
24
+ * <Avatar
25
+ * src="/path/to/image.jpg"
26
+ * fallback="JD"
27
+ * status="online"
28
+ * />
29
+ * ```
30
+ */
31
+ declare const Avatar: import("svelte").Component<{
32
+ class?: string;
33
+ id?: any;
34
+ src: any;
35
+ alt: any;
36
+ name: any;
37
+ fallback: any;
38
+ gravatarEmail: any;
39
+ size?: string;
40
+ shape?: string;
41
+ status: any;
42
+ bgColor: any;
43
+ bordered?: boolean;
44
+ shadowed?: boolean;
45
+ initialsGenerator: any;
46
+ }, {}, "">;
47
+ type Avatar = ReturnType<typeof Avatar>;
48
+ export default Avatar;
@@ -0,0 +1,185 @@
1
+ <!--
2
+ @component
3
+ AvatarGroup - A component for displaying multiple avatars in a compact, overlapping layout.
4
+ Provides consistent styling, accessibility features, and overflow handling.
5
+
6
+ Usage:
7
+ ```svelte
8
+ <AvatarGroup>
9
+ <Avatar src="/user1.jpg" alt="User 1" />
10
+ <Avatar src="/user2.jpg" alt="User 2" />
11
+ <Avatar src="/user3.jpg" alt="User 3" />
12
+ </AvatarGroup>
13
+
14
+ <AvatarGroup max={3} total={10}>
15
+ <Avatar name="John Doe" />
16
+ <Avatar name="Jane Smith" />
17
+ <Avatar name="Bob Johnson" />
18
+ </AvatarGroup>
19
+ ```
20
+ -->
21
+ <script>
22
+ import { setContext } from "svelte"
23
+
24
+ const {
25
+ /** @type {string} - Additional CSS classes */
26
+ class: className = "",
27
+
28
+ /** @type {string} - HTML id for accessibility */
29
+ id = crypto.randomUUID(),
30
+
31
+ /** @type {string} - Size of the avatars (xs, sm, md, lg, xl) */
32
+ size = "md",
33
+
34
+ /** @type {number} - Maximum number of avatars to display */
35
+ max,
36
+
37
+ /** @type {number} - Total number of avatars (for overflow count) */
38
+ total,
39
+
40
+ /** @type {number} - Spacing between avatars (-8 to 8) */
41
+ spacing = -4,
42
+
43
+ /** @type {boolean} - Whether to show a border around avatars */
44
+ bordered = true,
45
+
46
+ /** @type {string} - ARIA label for the group */
47
+ ariaLabel = "Avatar group",
48
+
49
+ children,
50
+ } = $props()
51
+
52
+ // Provide context for child avatars
53
+ $effect(() => {
54
+ setContext("avatarGroup", {
55
+ size,
56
+ bordered,
57
+ })
58
+ })
59
+
60
+ // Determine spacing class based on the spacing prop
61
+ const spacingClass = $derived(`avatar-group-spacing-${spacing}`)
62
+
63
+ // Determine if we need to show overflow
64
+ const showOverflow = $derived(max !== undefined && total !== undefined && total > max)
65
+
66
+ // Calculate overflow count
67
+ const overflowCount = $derived(showOverflow ? total - max : 0)
68
+ </script>
69
+
70
+ <div
71
+ {id}
72
+ class="
73
+ avatar-group
74
+ {spacingClass}
75
+ {className}
76
+ "
77
+ role="group"
78
+ aria-label={ariaLabel}
79
+ >
80
+ <div class="avatar-group-items">
81
+ {@render children?.()}
82
+
83
+ {#if showOverflow}
84
+ <div class="avatar-group-overflow">
85
+ <span class="avatar-group-overflow-text">+{overflowCount}</span>
86
+ </div>
87
+ {/if}
88
+ </div>
89
+ </div>
90
+
91
+ <style>
92
+ @reference "../../twintrinsic.css";
93
+
94
+ .avatar-group {
95
+ @apply inline-flex;
96
+ }
97
+
98
+ .avatar-group-items {
99
+ @apply flex items-center;
100
+ }
101
+
102
+ /* Spacing classes */
103
+ .avatar-group-spacing-8 :global(.avatar) {
104
+ @apply ml-8;
105
+ }
106
+
107
+ .avatar-group-spacing-6 :global(.avatar) {
108
+ @apply ml-6;
109
+ }
110
+
111
+ .avatar-group-spacing-4 :global(.avatar) {
112
+ @apply ml-4;
113
+ }
114
+
115
+ .avatar-group-spacing-2 :global(.avatar) {
116
+ @apply ml-2;
117
+ }
118
+
119
+ .avatar-group-spacing-0 :global(.avatar) {
120
+ @apply ml-0;
121
+ }
122
+
123
+ .avatar-group-spacing--2 :global(.avatar) {
124
+ @apply -ml-2;
125
+ }
126
+
127
+ .avatar-group-spacing--4 :global(.avatar) {
128
+ @apply -ml-4;
129
+ }
130
+
131
+ .avatar-group-spacing--6 :global(.avatar) {
132
+ @apply -ml-6;
133
+ }
134
+
135
+ .avatar-group-spacing--8 :global(.avatar) {
136
+ @apply -ml-8;
137
+ }
138
+
139
+ /* Remove margin from first avatar */
140
+ .avatar-group-items > :global(:first-child) {
141
+ @apply ml-0;
142
+ }
143
+
144
+ /* Overflow counter */
145
+ .avatar-group-overflow {
146
+ @apply flex items-center justify-center;
147
+ @apply bg-surface dark:bg-surface text-text dark:text-text;
148
+ @apply rounded-full overflow-hidden;
149
+ @apply border-2 border-background dark:border-background;
150
+ }
151
+
152
+ .avatar-group-overflow-text {
153
+ @apply font-medium;
154
+ }
155
+
156
+ /* Inherit size from context */
157
+ .avatar-group-overflow {
158
+ @apply w-10 h-10 text-base;
159
+ }
160
+
161
+ :global(.avatar-group-items .avatar-xs) ~ .avatar-group-overflow,
162
+ :global(.avatar-xs) ~ .avatar-group-overflow {
163
+ @apply w-6 h-6 text-xs;
164
+ }
165
+
166
+ :global(.avatar-group-items .avatar-sm) ~ .avatar-group-overflow,
167
+ :global(.avatar-sm) ~ .avatar-group-overflow {
168
+ @apply w-8 h-8 text-sm;
169
+ }
170
+
171
+ :global(.avatar-group-items .avatar-md) ~ .avatar-group-overflow,
172
+ :global(.avatar-md) ~ .avatar-group-overflow {
173
+ @apply w-10 h-10 text-base;
174
+ }
175
+
176
+ :global(.avatar-group-items .avatar-lg) ~ .avatar-group-overflow,
177
+ :global(.avatar-lg) ~ .avatar-group-overflow {
178
+ @apply w-12 h-12 text-lg;
179
+ }
180
+
181
+ :global(.avatar-group-items .avatar-xl) ~ .avatar-group-overflow,
182
+ :global(.avatar-xl) ~ .avatar-group-overflow {
183
+ @apply w-16 h-16 text-xl;
184
+ }
185
+ </style>
@@ -0,0 +1,46 @@
1
+ export default AvatarGroup;
2
+ type AvatarGroup = {
3
+ $on?(type: string, callback: (e: any) => void): () => void;
4
+ $set?(props: Partial<$$ComponentProps>): void;
5
+ };
6
+ /**
7
+ * AvatarGroup - A component for displaying multiple avatars in a compact, overlapping layout.
8
+ * Provides consistent styling, accessibility features, and overflow handling.
9
+ *
10
+ * Usage:
11
+ * ```svelte
12
+ * <AvatarGroup>
13
+ * <Avatar src="/user1.jpg" alt="User 1" />
14
+ * <Avatar src="/user2.jpg" alt="User 2" />
15
+ * <Avatar src="/user3.jpg" alt="User 3" />
16
+ * </AvatarGroup>
17
+ *
18
+ * <AvatarGroup max={3} total={10}>
19
+ * <Avatar name="John Doe" />
20
+ * <Avatar name="Jane Smith" />
21
+ * <Avatar name="Bob Johnson" />
22
+ * </AvatarGroup>
23
+ * ```
24
+ */
25
+ declare const AvatarGroup: import("svelte").Component<{
26
+ class?: string;
27
+ id?: any;
28
+ size?: string;
29
+ max: any;
30
+ total: any;
31
+ spacing?: any;
32
+ bordered?: boolean;
33
+ ariaLabel?: string;
34
+ children: any;
35
+ }, {}, "">;
36
+ type $$ComponentProps = {
37
+ class?: string;
38
+ id?: any;
39
+ size?: string;
40
+ max: any;
41
+ total: any;
42
+ spacing?: any;
43
+ bordered?: boolean;
44
+ ariaLabel?: string;
45
+ children: any;
46
+ };