@getmicdrop/svelte-components 5.14.0 → 5.16.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 (56) hide show
  1. package/dist/calendar/Calendar/MiniMonthCalendar.svelte +4 -4
  2. package/dist/calendar/PublicCard/PublicCard.svelte +3 -3
  3. package/dist/index.spec.js +1 -1
  4. package/dist/patterns/chat/ChatActivityNotice.svelte +41 -0
  5. package/dist/patterns/chat/ChatActivityNotice.svelte.d.ts +21 -0
  6. package/dist/patterns/chat/ChatActivityNotice.svelte.d.ts.map +1 -0
  7. package/dist/patterns/chat/ChatBubble.svelte +95 -0
  8. package/dist/patterns/chat/ChatBubble.svelte.d.ts +31 -0
  9. package/dist/patterns/chat/ChatBubble.svelte.d.ts.map +1 -0
  10. package/dist/patterns/chat/ChatContainer.svelte +46 -0
  11. package/dist/patterns/chat/ChatContainer.svelte.d.ts +21 -0
  12. package/dist/patterns/chat/ChatContainer.svelte.d.ts.map +1 -0
  13. package/dist/patterns/chat/ChatDateDivider.svelte +27 -0
  14. package/dist/patterns/chat/ChatDateDivider.svelte.d.ts +10 -0
  15. package/dist/patterns/chat/ChatDateDivider.svelte.d.ts.map +1 -0
  16. package/dist/patterns/chat/ChatInvitationBubble.svelte +37 -0
  17. package/dist/patterns/chat/ChatInvitationBubble.svelte.d.ts +12 -0
  18. package/dist/patterns/chat/ChatInvitationBubble.svelte.d.ts.map +1 -0
  19. package/dist/patterns/chat/ChatInvitationNotice.svelte +27 -0
  20. package/dist/patterns/chat/ChatInvitationNotice.svelte.d.ts +10 -0
  21. package/dist/patterns/chat/ChatInvitationNotice.svelte.d.ts.map +1 -0
  22. package/dist/patterns/chat/ChatMessageGroup.svelte +57 -0
  23. package/dist/patterns/chat/ChatMessageGroup.svelte.d.ts +25 -0
  24. package/dist/patterns/chat/ChatMessageGroup.svelte.d.ts.map +1 -0
  25. package/dist/patterns/chat/ChatSlotUpdate.svelte +46 -0
  26. package/dist/patterns/chat/ChatSlotUpdate.svelte.d.ts +16 -0
  27. package/dist/patterns/chat/ChatSlotUpdate.svelte.d.ts.map +1 -0
  28. package/dist/patterns/chat/ChatStatusBadge.svelte +91 -0
  29. package/dist/patterns/chat/ChatStatusBadge.svelte.d.ts +22 -0
  30. package/dist/patterns/chat/ChatStatusBadge.svelte.d.ts.map +1 -0
  31. package/dist/patterns/chat/ChatStatusTransition.svelte +64 -0
  32. package/dist/patterns/chat/ChatStatusTransition.svelte.d.ts +19 -0
  33. package/dist/patterns/chat/ChatStatusTransition.svelte.d.ts.map +1 -0
  34. package/dist/patterns/chat/ChatTextBubble.svelte +41 -0
  35. package/dist/patterns/chat/ChatTextBubble.svelte.d.ts +19 -0
  36. package/dist/patterns/chat/ChatTextBubble.svelte.d.ts.map +1 -0
  37. package/dist/patterns/chat/index.d.ts +12 -0
  38. package/dist/patterns/chat/index.d.ts.map +1 -0
  39. package/dist/patterns/chat/index.js +22 -0
  40. package/dist/patterns/index.d.ts +1 -0
  41. package/dist/patterns/index.js +3 -0
  42. package/dist/patterns/navigation/BottomNav.svelte +1 -1
  43. package/dist/patterns/navigation/Header.svelte +1 -1
  44. package/dist/primitives/BottomSheet/BottomSheet.svelte +18 -3
  45. package/dist/primitives/BottomSheet/BottomSheet.svelte.d.ts +2 -0
  46. package/dist/primitives/BottomSheet/BottomSheet.svelte.d.ts.map +1 -1
  47. package/dist/primitives/Button/Button.svelte +1 -1
  48. package/dist/primitives/Drawer/Drawer.svelte +1 -9
  49. package/dist/primitives/Drawer/Drawer.svelte.d.ts.map +1 -1
  50. package/dist/primitives/Modal/Modal.svelte +2 -2
  51. package/dist/recipes/ImageUploader/ImageUploader.svelte +1 -2
  52. package/dist/recipes/SuperLogin/SuperLogin.svelte +7 -7
  53. package/dist/services/ShowService.js +1 -1
  54. package/dist/utils/greetings.js +3 -3
  55. package/dist/utils/imageValidation.js +1 -1
  56. package/package.json +1 -1
@@ -0,0 +1,91 @@
1
+ <script lang="ts">
2
+ /**
3
+ * ChatStatusBadge - Status indicator for chat activity feeds
4
+ *
5
+ * Displays status changes (Confirmed, Declined, Invited, etc.) with
6
+ * appropriate colors and icons in a pill/badge format.
7
+ */
8
+ import type { Snippet, Component } from 'svelte';
9
+ import { classNames } from '../../utils/utils.js';
10
+ import CheckmarkFilled from 'carbon-icons-svelte/lib/CheckmarkFilled.svelte';
11
+ import CloseFilled from 'carbon-icons-svelte/lib/CloseFilled.svelte';
12
+ import SendAltFilled from 'carbon-icons-svelte/lib/SendAltFilled.svelte';
13
+
14
+ type StatusType = 'confirmed' | 'declined' | 'canceled' | 'invited' | 'pending' | string;
15
+
16
+ interface Props {
17
+ /** Status value */
18
+ status: StatusType;
19
+ /** Show as outbound style (right-aligned context) */
20
+ outbound?: boolean;
21
+ /** Additional CSS classes */
22
+ className?: string;
23
+ /** Optional custom icon */
24
+ icon?: Snippet;
25
+ }
26
+
27
+ let {
28
+ status,
29
+ outbound = false,
30
+ className = '',
31
+ icon,
32
+ }: Props = $props();
33
+
34
+ interface StatusStyle {
35
+ textColor: string;
36
+ bgColor: string;
37
+ icon: Component<{ class?: string }> | null;
38
+ }
39
+
40
+ function getStatusStyle(s: string): StatusStyle {
41
+ switch (s?.toLowerCase()) {
42
+ case 'confirmed':
43
+ return {
44
+ textColor: 'text-green-600',
45
+ bgColor: 'bg-green-50 dark:bg-green-900/20',
46
+ icon: CheckmarkFilled,
47
+ };
48
+ case 'declined':
49
+ case 'canceled':
50
+ return {
51
+ textColor: 'text-red-600',
52
+ bgColor: 'bg-red-50 dark:bg-red-900/20',
53
+ icon: CloseFilled,
54
+ };
55
+ case 'invited':
56
+ return {
57
+ textColor: 'text-blue-600',
58
+ bgColor: 'bg-blue-50 dark:bg-blue-900/20',
59
+ icon: SendAltFilled,
60
+ };
61
+ default:
62
+ return {
63
+ textColor: 'text-gray-600',
64
+ bgColor: 'bg-gray-100 dark:bg-gray-800',
65
+ icon: null,
66
+ };
67
+ }
68
+ }
69
+
70
+ let style = $derived(getStatusStyle(status));
71
+
72
+ let badgeClasses = $derived(
73
+ classNames(
74
+ 'px-4 py-2.5 rounded-2xl text-sm font-medium flex items-center gap-1.5',
75
+ style.bgColor,
76
+ style.textColor,
77
+ outbound ? 'rounded-br-sm' : 'rounded-bl-sm',
78
+ className
79
+ )
80
+ );
81
+ </script>
82
+
83
+ <div class={badgeClasses}>
84
+ {#if icon}
85
+ {@render icon()}
86
+ {:else if style.icon}
87
+ {@const IconComponent = style.icon}
88
+ <IconComponent class="w-4 h-4" />
89
+ {/if}
90
+ <span class="capitalize">{status}</span>
91
+ </div>
@@ -0,0 +1,22 @@
1
+ /**
2
+ * ChatStatusBadge - Status indicator for chat activity feeds
3
+ *
4
+ * Displays status changes (Confirmed, Declined, Invited, etc.) with
5
+ * appropriate colors and icons in a pill/badge format.
6
+ */
7
+ import type { Snippet, Component } from 'svelte';
8
+ type StatusType = 'confirmed' | 'declined' | 'canceled' | 'invited' | 'pending' | string;
9
+ interface Props {
10
+ /** Status value */
11
+ status: StatusType;
12
+ /** Show as outbound style (right-aligned context) */
13
+ outbound?: boolean;
14
+ /** Additional CSS classes */
15
+ className?: string;
16
+ /** Optional custom icon */
17
+ icon?: Snippet;
18
+ }
19
+ declare const ChatStatusBadge: Component<Props, {}, "">;
20
+ type ChatStatusBadge = ReturnType<typeof ChatStatusBadge>;
21
+ export default ChatStatusBadge;
22
+ //# sourceMappingURL=ChatStatusBadge.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChatStatusBadge.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/patterns/chat/ChatStatusBadge.svelte.ts"],"names":[],"mappings":"AAGA;;;;;KAKK;AACL,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAO/C,KAAK,UAAU,GAAG,WAAW,GAAG,UAAU,GAAG,UAAU,GAAG,SAAS,GAAG,SAAS,GAAG,MAAM,CAAC;AAEzF,UAAU,KAAK;IACb,mBAAmB;IACnB,MAAM,EAAE,UAAU,CAAC;IACnB,qDAAqD;IACrD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,6BAA6B;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2BAA2B;IAC3B,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAgFH,QAAA,MAAM,eAAe,0BAAwC,CAAC;AAC9D,KAAK,eAAe,GAAG,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC;AAC1D,eAAe,eAAe,CAAC"}
@@ -0,0 +1,64 @@
1
+ <script lang="ts">
2
+ /**
3
+ * ChatStatusTransition - Status change display with icons
4
+ *
5
+ * Shows "{fromStatus} → {toStatus}" with colored icons for each status.
6
+ * Used in activity notices to show silent status changes.
7
+ */
8
+ import type { Component } from 'svelte';
9
+ import { classNames } from '../../utils/utils.js';
10
+ import CheckmarkFilled from 'carbon-icons-svelte/lib/CheckmarkFilled.svelte';
11
+ import CloseFilled from 'carbon-icons-svelte/lib/CloseFilled.svelte';
12
+ import SendAltFilled from 'carbon-icons-svelte/lib/SendAltFilled.svelte';
13
+
14
+ interface Props {
15
+ /** Original status */
16
+ fromStatus: string;
17
+ /** New status */
18
+ toStatus: string;
19
+ /** Additional CSS classes */
20
+ className?: string;
21
+ }
22
+
23
+ let {
24
+ fromStatus,
25
+ toStatus,
26
+ className = '',
27
+ }: Props = $props();
28
+
29
+ interface StatusStyle {
30
+ color: string;
31
+ icon: Component<{ class?: string }> | null;
32
+ }
33
+
34
+ function getStatusStyle(status: string): StatusStyle {
35
+ switch (status?.toLowerCase()) {
36
+ case 'confirmed':
37
+ return { color: 'text-green-600', icon: CheckmarkFilled };
38
+ case 'declined':
39
+ case 'canceled':
40
+ return { color: 'text-red-600', icon: CloseFilled };
41
+ case 'invited':
42
+ return { color: 'text-blue-600', icon: SendAltFilled };
43
+ default:
44
+ return { color: 'text-gray-600', icon: null };
45
+ }
46
+ }
47
+
48
+ let fromStyle = $derived(getStatusStyle(fromStatus));
49
+ let toStyle = $derived(getStatusStyle(toStatus));
50
+ </script>
51
+
52
+ <span class={classNames('text-xs font-medium flex items-center gap-1', className)}>
53
+ {#if fromStyle.icon}
54
+ {@const FromIcon = fromStyle.icon}
55
+ <FromIcon class="w-3 h-3 {fromStyle.color}" />
56
+ {/if}
57
+ <span class={fromStyle.color}>{fromStatus}</span>
58
+ <span class="text-gray-400 mx-1">→</span>
59
+ {#if toStyle.icon}
60
+ {@const ToIcon = toStyle.icon}
61
+ <ToIcon class="w-3 h-3 {toStyle.color}" />
62
+ {/if}
63
+ <span class={toStyle.color}>{toStatus}</span>
64
+ </span>
@@ -0,0 +1,19 @@
1
+ /**
2
+ * ChatStatusTransition - Status change display with icons
3
+ *
4
+ * Shows "{fromStatus} → {toStatus}" with colored icons for each status.
5
+ * Used in activity notices to show silent status changes.
6
+ */
7
+ import type { Component } from 'svelte';
8
+ interface Props {
9
+ /** Original status */
10
+ fromStatus: string;
11
+ /** New status */
12
+ toStatus: string;
13
+ /** Additional CSS classes */
14
+ className?: string;
15
+ }
16
+ declare const ChatStatusTransition: Component<Props, {}, "">;
17
+ type ChatStatusTransition = ReturnType<typeof ChatStatusTransition>;
18
+ export default ChatStatusTransition;
19
+ //# sourceMappingURL=ChatStatusTransition.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChatStatusTransition.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/patterns/chat/ChatStatusTransition.svelte.ts"],"names":[],"mappings":"AAGA;;;;;KAKK;AACL,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAOtC,UAAU,KAAK;IACb,sBAAsB;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,6BAA6B;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAwDH,QAAA,MAAM,oBAAoB,0BAAwC,CAAC;AACnE,KAAK,oBAAoB,GAAG,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAC;AACpE,eAAe,oBAAoB,CAAC"}
@@ -0,0 +1,41 @@
1
+ <script lang="ts">
2
+ /**
3
+ * ChatTextBubble - Simple text bubble without the full ChatBubble wrapper
4
+ *
5
+ * Just the bubble itself, for use within ChatMessageGroup or other contexts
6
+ * where you don't need avatar/timestamp handling.
7
+ */
8
+ import type { Snippet } from 'svelte';
9
+ import { classNames } from '../../utils/utils.js';
10
+
11
+ interface Props {
12
+ /** Direction - inbound (gray) or outbound (blue) */
13
+ direction?: 'inbound' | 'outbound';
14
+ /** Additional CSS classes */
15
+ className?: string;
16
+ /** Content */
17
+ children?: Snippet;
18
+ }
19
+
20
+ let {
21
+ direction = 'inbound',
22
+ className = '',
23
+ children,
24
+ }: Props = $props();
25
+
26
+ let isOutbound = $derived(direction === 'outbound');
27
+
28
+ let bubbleClasses = $derived(
29
+ classNames(
30
+ 'px-4 py-2.5 rounded-2xl text-sm',
31
+ isOutbound
32
+ ? 'bg-blue-600 text-white rounded-br-sm'
33
+ : 'bg-gray-100 dark:bg-gray-800 text-gray-900 dark:text-white rounded-bl-sm',
34
+ className
35
+ )
36
+ );
37
+ </script>
38
+
39
+ <div class={bubbleClasses}>
40
+ {@render children?.()}
41
+ </div>
@@ -0,0 +1,19 @@
1
+ /**
2
+ * ChatTextBubble - Simple text bubble without the full ChatBubble wrapper
3
+ *
4
+ * Just the bubble itself, for use within ChatMessageGroup or other contexts
5
+ * where you don't need avatar/timestamp handling.
6
+ */
7
+ import type { Snippet } from 'svelte';
8
+ interface Props {
9
+ /** Direction - inbound (gray) or outbound (blue) */
10
+ direction?: 'inbound' | 'outbound';
11
+ /** Additional CSS classes */
12
+ className?: string;
13
+ /** Content */
14
+ children?: Snippet;
15
+ }
16
+ declare const ChatTextBubble: import("svelte").Component<Props, {}, "">;
17
+ type ChatTextBubble = ReturnType<typeof ChatTextBubble>;
18
+ export default ChatTextBubble;
19
+ //# sourceMappingURL=ChatTextBubble.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChatTextBubble.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/patterns/chat/ChatTextBubble.svelte.ts"],"names":[],"mappings":"AAGA;;;;;KAKK;AACL,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAIpC,UAAU,KAAK;IACb,oDAAoD;IACpD,SAAS,CAAC,EAAE,SAAS,GAAG,UAAU,CAAC;IACnC,6BAA6B;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAgCH,QAAA,MAAM,cAAc,2CAAwC,CAAC;AAC7D,KAAK,cAAc,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;AACxD,eAAe,cAAc,CAAC"}
@@ -0,0 +1,12 @@
1
+ export { default as ChatContainer } from "./ChatContainer.svelte";
2
+ export { default as ChatMessageGroup } from "./ChatMessageGroup.svelte";
3
+ export { default as ChatBubble } from "./ChatBubble.svelte";
4
+ export { default as ChatTextBubble } from "./ChatTextBubble.svelte";
5
+ export { default as ChatInvitationBubble } from "./ChatInvitationBubble.svelte";
6
+ export { default as ChatStatusBadge } from "./ChatStatusBadge.svelte";
7
+ export { default as ChatStatusTransition } from "./ChatStatusTransition.svelte";
8
+ export { default as ChatSlotUpdate } from "./ChatSlotUpdate.svelte";
9
+ export { default as ChatDateDivider } from "./ChatDateDivider.svelte";
10
+ export { default as ChatActivityNotice } from "./ChatActivityNotice.svelte";
11
+ export { default as ChatInvitationNotice } from "./ChatInvitationNotice.svelte";
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/patterns/chat/index.js"],"names":[],"mappings":""}
@@ -0,0 +1,22 @@
1
+ // =============================================================================
2
+ // CHAT PATTERNS - Chat interface components
3
+ // =============================================================================
4
+
5
+ // Core layout
6
+ export { default as ChatContainer } from './ChatContainer.svelte';
7
+ export { default as ChatMessageGroup } from './ChatMessageGroup.svelte';
8
+
9
+ // Message bubbles
10
+ export { default as ChatBubble } from './ChatBubble.svelte';
11
+ export { default as ChatTextBubble } from './ChatTextBubble.svelte';
12
+ export { default as ChatInvitationBubble } from './ChatInvitationBubble.svelte';
13
+
14
+ // Status displays
15
+ export { default as ChatStatusBadge } from './ChatStatusBadge.svelte';
16
+ export { default as ChatStatusTransition } from './ChatStatusTransition.svelte';
17
+ export { default as ChatSlotUpdate } from './ChatSlotUpdate.svelte';
18
+
19
+ // Dividers and notices
20
+ export { default as ChatDateDivider } from './ChatDateDivider.svelte';
21
+ export { default as ChatActivityNotice } from './ChatActivityNotice.svelte';
22
+ export { default as ChatInvitationNotice } from './ChatInvitationNotice.svelte';
@@ -1,3 +1,4 @@
1
+ export * from "./chat/index.js";
1
2
  export * from "./forms/index.js";
2
3
  export * from "./navigation/index.js";
3
4
  export * from "./page/index.js";
@@ -2,6 +2,9 @@
2
2
  // PATTERNS - Layout & flow components (Layer 3)
3
3
  // =============================================================================
4
4
 
5
+ // Chat - re-export from chat/index.js
6
+ export * from './chat/index.js';
7
+
5
8
  // Forms - re-export from forms/index.js
6
9
  export * from './forms/index.js';
7
10
 
@@ -42,7 +42,7 @@
42
42
  }
43
43
  const events = await res.json();
44
44
  invitationCount = events.filter((event: { acceptedState: number }) => event.acceptedState === 0).length;
45
- } catch (err) {
45
+ } catch (_err) {
46
46
  // Silently fail - this is non-critical UI enhancement
47
47
  }
48
48
  }
@@ -5,7 +5,7 @@
5
5
  import Logo from "../../assets/images/Logo.png";
6
6
  import Avatar from "../../primitives/Avatar/Avatar.svelte";
7
7
  import DarkModeToggle from "../../primitives/DarkModeToggle.svelte";
8
- import Icon from "../../primitives/Icons/Icon.svelte";
8
+ import IconComponent from "../../primitives/Icons/Icon.svelte";
9
9
  import ChevronLeft from "../../primitives/Icons/ChevronLeft.svelte";
10
10
  import Button from "../../primitives/Button/Button.svelte";
11
11
  import MenuItem from "../../primitives/MenuItem/MenuItem.svelte";
@@ -10,6 +10,8 @@
10
10
  open?: boolean;
11
11
  /** Title displayed in the header */
12
12
  title?: string;
13
+ /** Keep as bottom sheet at all screen sizes (never convert to centered modal) */
14
+ alwaysSheet?: boolean;
13
15
  /** Callback when the sheet should close */
14
16
  onclose?: () => void;
15
17
  /** Main content */
@@ -21,6 +23,7 @@
21
23
  let {
22
24
  open = $bindable(false),
23
25
  title = '',
26
+ alwaysSheet = false,
24
27
  onclose,
25
28
  children,
26
29
  actions
@@ -57,6 +60,18 @@
57
60
  document.body.style.overflow = "";
58
61
  }
59
62
  });
63
+
64
+ let backdropClass = $derived(
65
+ alwaysSheet
66
+ ? "fixed inset-0 z-50 flex items-end bg-gray-900/50 dark:bg-gray-900/80"
67
+ : "fixed inset-0 z-50 flex items-end md:items-center md:justify-center bg-gray-900/50 dark:bg-gray-900/80"
68
+ );
69
+
70
+ let sheetClass = $derived(
71
+ alwaysSheet
72
+ ? "w-full max-h-[90dvh] bg-white dark:bg-gray-800 rounded-t-xl shadow-xl flex flex-col overflow-hidden"
73
+ : "w-full max-h-[90dvh] md:max-w-lg md:max-h-[80vh] md:m-4 bg-white dark:bg-gray-800 rounded-t-xl md:rounded-lg shadow-xl flex flex-col overflow-hidden"
74
+ );
60
75
  </script>
61
76
 
62
77
  <svelte:window onkeydown={handleKeydown} />
@@ -65,18 +80,18 @@
65
80
  <!-- svelte-ignore a11y_click_events_have_key_events -->
66
81
  <!-- svelte-ignore a11y_no_static_element_interactions -->
67
82
  <div
68
- class="fixed inset-0 z-50 flex items-end md:items-center md:justify-center bg-gray-900/50 dark:bg-gray-900/80"
83
+ class={backdropClass}
69
84
  onclick={handleBackdropClick}
70
85
  transition:fade={{ duration: 200 }}
71
86
  >
72
87
  <!-- svelte-ignore a11y_click_events_have_key_events -->
73
88
  <!-- svelte-ignore a11y_no_static_element_interactions -->
74
89
  <div
75
- class="w-full max-h-[90dvh] md:max-w-lg md:max-h-[80vh] md:m-4 bg-white dark:bg-gray-800 rounded-t-xl md:rounded-lg shadow-xl flex flex-col overflow-hidden"
90
+ class={sheetClass}
76
91
  onclick={(e) => e.stopPropagation()}
77
92
  transition:fly={{ y: 300, duration: 300, easing: cubicOut }}
78
93
  >
79
- <div class="flex justify-center pt-3 pb-2 shrink-0 md:hidden">
94
+ <div class="flex justify-center pt-3 pb-2 shrink-0 {alwaysSheet ? '' : 'md:hidden'}" >
80
95
  <div class="w-10 h-1 bg-gray-300 dark:bg-gray-600 rounded-full"></div>
81
96
  </div>
82
97
 
@@ -4,6 +4,8 @@ interface Props {
4
4
  open?: boolean;
5
5
  /** Title displayed in the header */
6
6
  title?: string;
7
+ /** Keep as bottom sheet at all screen sizes (never convert to centered modal) */
8
+ alwaysSheet?: boolean;
7
9
  /** Callback when the sheet should close */
8
10
  onclose?: () => void;
9
11
  /** Main content */
@@ -1 +1 @@
1
- {"version":3,"file":"BottomSheet.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/primitives/BottomSheet/BottomSheet.svelte.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAIpC,UAAU,KAAK;IACb,0CAA0C;IAC1C,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,oCAAoC;IACpC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,2CAA2C;IAC3C,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,mBAAmB;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,oCAAoC;IACpC,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAoFH,QAAA,MAAM,WAAW,+CAAwC,CAAC;AAC1D,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;AAClD,eAAe,WAAW,CAAC"}
1
+ {"version":3,"file":"BottomSheet.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/primitives/BottomSheet/BottomSheet.svelte.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAIpC,UAAU,KAAK;IACb,0CAA0C;IAC1C,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,oCAAoC;IACpC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iFAAiF;IACjF,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,2CAA2C;IAC3C,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,mBAAmB;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,oCAAoC;IACpC,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAiGH,QAAA,MAAM,WAAW,+CAAwC,CAAC;AAC1D,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;AAClD,eAAe,WAAW,CAAC"}
@@ -118,7 +118,7 @@
118
118
  link: "text-blue-700 bg-transparent border-transparent hover:underline dark:text-blue-500",
119
119
  icon: "text-gray-500 bg-transparent border-transparent hover:bg-gray-100 dark:text-gray-400 dark:hover:bg-gray-700",
120
120
  toggle: "text-gray-900 bg-gray-100 border border-gray-200 hover:bg-gray-200 dark:bg-gray-700 dark:text-white dark:border-gray-600 dark:hover:bg-gray-600",
121
- success: "text-white bg-green-600 border border-green-600",
121
+ success: "text-white bg-green-600 border border-green-600 hover:bg-green-700 dark:bg-green-600 dark:hover:bg-green-700",
122
122
  };
123
123
 
124
124
  // Active state classes for ghost and toggle
@@ -130,17 +130,15 @@
130
130
  }
131
131
  }
132
132
 
133
- // Lock body scroll when drawer is open
133
+ // Focus management when drawer is open (no body scroll lock — allow background scrolling)
134
134
  $effect(() => {
135
135
  if (typeof document !== "undefined") {
136
136
  if (isVisible) {
137
- document.body.style.overflow = "hidden";
138
137
  // Store previously focused element and focus drawer
139
138
  previouslyFocusedElement = document.activeElement;
140
139
  // Use setTimeout to ensure drawer is rendered before focusing
141
140
  setTimeout(() => drawerElement?.focus(), 0);
142
141
  } else {
143
- document.body.style.overflow = "";
144
142
  // Restore focus when closing
145
143
  if (previouslyFocusedElement && previouslyFocusedElement instanceof HTMLElement) {
146
144
  previouslyFocusedElement.focus();
@@ -148,12 +146,6 @@
148
146
  }
149
147
  }
150
148
  });
151
-
152
- onDestroy(() => {
153
- if (typeof document !== "undefined") {
154
- document.body.style.overflow = "";
155
- }
156
- });
157
149
  </script>
158
150
 
159
151
  <svelte:window onkeydown={handleKeydown} />
@@ -1 +1 @@
1
- {"version":3,"file":"Drawer.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/primitives/Drawer/Drawer.svelte.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAGpC,UAAU,KAAK;IACb,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAmMH,QAAA,MAAM,MAAM,+CAAwC,CAAC;AACrD,KAAK,MAAM,GAAG,UAAU,CAAC,OAAO,MAAM,CAAC,CAAC;AACxC,eAAe,MAAM,CAAC"}
1
+ {"version":3,"file":"Drawer.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/primitives/Drawer/Drawer.svelte.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAGpC,UAAU,KAAK;IACb,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AA2LH,QAAA,MAAM,MAAM,+CAAwC,CAAC;AACrD,KAAK,MAAM,GAAG,UAAU,CAAC,OAAO,MAAM,CAAC,CAAC;AACxC,eAAe,MAAM,CAAC"}
@@ -27,8 +27,8 @@
27
27
  }} */
28
28
  let {
29
29
  open = $bindable(false),
30
- isProcessing = false,
31
- isSuccess = false,
30
+ isProcessing: _isProcessing = false,
31
+ isSuccess: _isSuccess = false,
32
32
  size = "md",
33
33
  persistent = false,
34
34
  haptic = true,
@@ -627,7 +627,7 @@
627
627
  {:else}
628
628
  <!-- Empty dropzone with direct drag-drop support -->
629
629
  <div
630
- class="{shapeAspects[shape]} filepond-wrapper-single {shape === 'wide' ? 'filepond-wide' : ''}
630
+ class="{shapeAspects[shape]} filepond-wrapper-single rounded-xl {shape === 'wide' ? 'filepond-wide' : ''}
631
631
  {isDropzoneDragOver ? 'dropzone-drag-over' : ''}"
632
632
  role="button"
633
633
  tabindex="0"
@@ -883,7 +883,6 @@
883
883
  /* Single mode dropzone styling */
884
884
  .filepond-wrapper-single {
885
885
  border: 2px dashed rgb(209 213 219); /* gray-300 */
886
- border-radius: 0.75rem; /* rounded-xl */
887
886
  background-color: rgb(249 250 251); /* gray-50 */
888
887
  transition-property: color, background-color, border-color;
889
888
  transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
@@ -112,7 +112,7 @@
112
112
  }
113
113
  });
114
114
 
115
- let authError = $state("");
115
+ let _authError = $state("");
116
116
  let email = $state((() => userEmail)());
117
117
  let password = $state("");
118
118
  let errors = $state({});
@@ -181,7 +181,7 @@
181
181
  email = rememberedUser.email;
182
182
  }
183
183
  }
184
- } catch (e) {
184
+ } catch (_e) {
185
185
  // Ignore parse errors
186
186
  }
187
187
 
@@ -205,7 +205,7 @@
205
205
 
206
206
  // Handle browser back/forward buttons
207
207
  const handlePopState = () => {
208
- const path = window.location.pathname;
208
+ const _path = window.location.pathname;
209
209
  };
210
210
 
211
211
  window.addEventListener("popstate", handlePopState);
@@ -275,7 +275,7 @@
275
275
  async function handleSubmit(event) {
276
276
  event.preventDefault();
277
277
  isLoading = true;
278
- authError = "";
278
+ _authError = "";
279
279
  // Try to get values from DOM first (for testing frameworks), fall back to Svelte state
280
280
  const emailInput = /** @type {HTMLInputElement|null} */ (document.querySelector('#email'));
281
281
  const passwordInput = /** @type {HTMLInputElement|null} */ (document.querySelector('#password'));
@@ -436,7 +436,7 @@
436
436
  });
437
437
 
438
438
  try {
439
- const [_, response] = await Promise.all([minDelay, apiCall]);
439
+ const [_delay, _response] = await Promise.all([minDelay, apiCall]);
440
440
  isLoading = false;
441
441
 
442
442
  // Always show success to prevent email enumeration
@@ -483,7 +483,7 @@
483
483
  });
484
484
 
485
485
  try {
486
- const [_, response] = await Promise.all([minDelay, apiCall]);
486
+ const [_delay2, _response2] = await Promise.all([minDelay, apiCall]);
487
487
 
488
488
  isLoading = false;
489
489
 
@@ -549,7 +549,7 @@
549
549
  'rememberedUser',
550
550
  JSON.stringify({ email: emailVal, firstName: firstNameVal })
551
551
  );
552
- } catch (e) {
552
+ } catch (_e) {
553
553
  // Ignore storage errors
554
554
  }
555
555
  }
@@ -120,7 +120,7 @@ export async function sendVenueMessage(inviteId, message) {
120
120
  if (text) {
121
121
  try {
122
122
  result = JSON.parse(text);
123
- } catch (e) {
123
+ } catch (_e) {
124
124
  // Empty response is fine
125
125
  }
126
126
  }
@@ -142,7 +142,7 @@ export function getGreeting(name) {
142
142
  return greeting;
143
143
  }
144
144
  }
145
- } catch (e) {
145
+ } catch (_e) {
146
146
  // localStorage unavailable or parse error - continue to generate
147
147
  }
148
148
 
@@ -157,7 +157,7 @@ export function getGreeting(name) {
157
157
  day: currentDay,
158
158
  cachedName: name
159
159
  }));
160
- } catch (e) {
160
+ } catch (_e2) {
161
161
  // localStorage unavailable - greeting still works, just won't persist
162
162
  }
163
163
 
@@ -181,7 +181,7 @@ export function clearGreetingCache() {
181
181
  if (typeof window === 'undefined') return;
182
182
  try {
183
183
  localStorage.removeItem(STORAGE_KEY);
184
- } catch (e) {
184
+ } catch (_e) {
185
185
  // localStorage unavailable
186
186
  }
187
187
  }
@@ -61,7 +61,7 @@ export async function validateImage(file) {
61
61
  error: null,
62
62
  dimensions
63
63
  };
64
- } catch (error) {
64
+ } catch (_error) {
65
65
  return {
66
66
  valid: false,
67
67
  error: 'Failed to read image dimensions. Please try another file.',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@getmicdrop/svelte-components",
3
- "version": "5.14.0",
3
+ "version": "5.16.0",
4
4
  "description": "Shared component library for Micdrop applications",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",