@getmicdrop/svelte-components 5.13.0 → 5.15.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.
- package/dist/calendar/OrderSummary/OrderSummary.svelte +67 -7
- package/dist/calendar/OrderSummary/OrderSummary.svelte.d.ts +2 -0
- package/dist/calendar/OrderSummary/OrderSummary.svelte.d.ts.map +1 -1
- package/dist/index.spec.js +1 -1
- package/dist/patterns/chat/ChatActivityNotice.svelte +41 -0
- package/dist/patterns/chat/ChatActivityNotice.svelte.d.ts +21 -0
- package/dist/patterns/chat/ChatActivityNotice.svelte.d.ts.map +1 -0
- package/dist/patterns/chat/ChatBubble.svelte +95 -0
- package/dist/patterns/chat/ChatBubble.svelte.d.ts +31 -0
- package/dist/patterns/chat/ChatBubble.svelte.d.ts.map +1 -0
- package/dist/patterns/chat/ChatContainer.svelte +46 -0
- package/dist/patterns/chat/ChatContainer.svelte.d.ts +21 -0
- package/dist/patterns/chat/ChatContainer.svelte.d.ts.map +1 -0
- package/dist/patterns/chat/ChatDateDivider.svelte +27 -0
- package/dist/patterns/chat/ChatDateDivider.svelte.d.ts +10 -0
- package/dist/patterns/chat/ChatDateDivider.svelte.d.ts.map +1 -0
- package/dist/patterns/chat/ChatInvitationBubble.svelte +37 -0
- package/dist/patterns/chat/ChatInvitationBubble.svelte.d.ts +12 -0
- package/dist/patterns/chat/ChatInvitationBubble.svelte.d.ts.map +1 -0
- package/dist/patterns/chat/ChatInvitationNotice.svelte +27 -0
- package/dist/patterns/chat/ChatInvitationNotice.svelte.d.ts +10 -0
- package/dist/patterns/chat/ChatInvitationNotice.svelte.d.ts.map +1 -0
- package/dist/patterns/chat/ChatMessageGroup.svelte +57 -0
- package/dist/patterns/chat/ChatMessageGroup.svelte.d.ts +25 -0
- package/dist/patterns/chat/ChatMessageGroup.svelte.d.ts.map +1 -0
- package/dist/patterns/chat/ChatSlotUpdate.svelte +46 -0
- package/dist/patterns/chat/ChatSlotUpdate.svelte.d.ts +16 -0
- package/dist/patterns/chat/ChatSlotUpdate.svelte.d.ts.map +1 -0
- package/dist/patterns/chat/ChatStatusBadge.svelte +91 -0
- package/dist/patterns/chat/ChatStatusBadge.svelte.d.ts +22 -0
- package/dist/patterns/chat/ChatStatusBadge.svelte.d.ts.map +1 -0
- package/dist/patterns/chat/ChatStatusTransition.svelte +64 -0
- package/dist/patterns/chat/ChatStatusTransition.svelte.d.ts +19 -0
- package/dist/patterns/chat/ChatStatusTransition.svelte.d.ts.map +1 -0
- package/dist/patterns/chat/ChatTextBubble.svelte +41 -0
- package/dist/patterns/chat/ChatTextBubble.svelte.d.ts +19 -0
- package/dist/patterns/chat/ChatTextBubble.svelte.d.ts.map +1 -0
- package/dist/patterns/chat/index.d.ts +12 -0
- package/dist/patterns/chat/index.d.ts.map +1 -0
- package/dist/patterns/chat/index.js +22 -0
- package/dist/patterns/index.d.ts +1 -0
- package/dist/patterns/index.js +3 -0
- package/dist/primitives/Button/Button.spec.js +8 -6
- package/dist/primitives/Input/Input.svelte +1 -1
- package/dist/recipes/ImageUploader/ImageUploader.svelte +1 -2
- package/dist/tokens/__tests__/sizing.test.js +5 -7
- package/dist/tokens/sizing.d.ts +20 -19
- package/dist/tokens/sizing.d.ts.map +1 -1
- package/dist/tokens/sizing.js +20 -19
- package/package.json +1 -1
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
taxPercentage: 0,
|
|
27
27
|
},
|
|
28
28
|
onPriceUpdate,
|
|
29
|
+
giftCardApplied = null, // { code, giftCardAmount, giftCardBalance, stripeAmount, paymentType, requiresStripe }
|
|
29
30
|
} = $props();
|
|
30
31
|
|
|
31
32
|
// Helper to get effective price for a ticket (handles donation tickets)
|
|
@@ -127,7 +128,22 @@
|
|
|
127
128
|
|
|
128
129
|
let taxRate = $derived((venueServiceCharge.taxPercentage || 0) / 100);
|
|
129
130
|
let taxes = $derived(subtotal > 0 ? subtotal * taxRate : 0);
|
|
130
|
-
|
|
131
|
+
|
|
132
|
+
// Gift card derived values
|
|
133
|
+
let giftCardAmountDisplay = $derived(
|
|
134
|
+
giftCardApplied ? (giftCardApplied.giftCardAmount / 100).toFixed(2) : null
|
|
135
|
+
);
|
|
136
|
+
let giftCardRemainingBalance = $derived(
|
|
137
|
+
giftCardApplied ? ((giftCardApplied.giftCardBalance - giftCardApplied.giftCardAmount) / 100).toFixed(2) : null
|
|
138
|
+
);
|
|
139
|
+
|
|
140
|
+
// Total accounts for gift card deduction
|
|
141
|
+
let total = $derived(
|
|
142
|
+
Math.max(0, subtotal + fees + taxes
|
|
143
|
+
- (promoApplied && !currentPromoRule?.provideDiscount ? promoDiscount : 0)
|
|
144
|
+
- (giftCardApplied ? giftCardApplied.giftCardAmount / 100 : 0)
|
|
145
|
+
)
|
|
146
|
+
);
|
|
131
147
|
|
|
132
148
|
$effect(() => {
|
|
133
149
|
onPriceUpdate?.({ subtotal, fees, taxes, total, promoSavings });
|
|
@@ -206,11 +222,33 @@
|
|
|
206
222
|
<div class="flex justify-between text-gray-600 dark:text-gray-300">
|
|
207
223
|
<span>Taxes</span><span>${taxes.toFixed(2)}</span>
|
|
208
224
|
</div>
|
|
225
|
+
{#if giftCardApplied}
|
|
226
|
+
<div class="flex justify-between text-green-600 dark:text-green-500">
|
|
227
|
+
<span>Gift Card Applied</span>
|
|
228
|
+
<span>-${giftCardAmountDisplay}</span>
|
|
229
|
+
</div>
|
|
230
|
+
{#if giftCardRemainingBalance && parseFloat(giftCardRemainingBalance) > 0}
|
|
231
|
+
<div class="flex justify-between text-gray-500 dark:text-gray-400 text-xs">
|
|
232
|
+
<span>Gift card balance after order</span>
|
|
233
|
+
<span>${giftCardRemainingBalance}</span>
|
|
234
|
+
</div>
|
|
235
|
+
{/if}
|
|
236
|
+
{/if}
|
|
209
237
|
</div>
|
|
210
238
|
|
|
211
|
-
|
|
212
|
-
<
|
|
213
|
-
|
|
239
|
+
{#if giftCardApplied?.paymentType === 'gift_card_only'}
|
|
240
|
+
<div class="flex justify-between py-4 text-lg border-t border-gray-200 dark:border-gray-600">
|
|
241
|
+
<span class="font-semibold text-gray-900 dark:text-white">Amount Due</span>
|
|
242
|
+
<span class="font-bold text-green-600 dark:text-green-400">$0.00</span>
|
|
243
|
+
</div>
|
|
244
|
+
<p class="text-xs text-gray-500 dark:text-gray-400 text-center -mt-2 mb-2">
|
|
245
|
+
Fully covered by gift card
|
|
246
|
+
</p>
|
|
247
|
+
{:else}
|
|
248
|
+
<div class="flex justify-between {typography.h3} py-4 text-lg border-t border-gray-200 dark:border-gray-600">
|
|
249
|
+
<span>Total</span><span>${total.toFixed(2)}</span>
|
|
250
|
+
</div>
|
|
251
|
+
{/if}
|
|
214
252
|
{/if}
|
|
215
253
|
|
|
216
254
|
{#if totalQuantity > 0 && btnText === 'Place order'}
|
|
@@ -322,11 +360,33 @@
|
|
|
322
360
|
<div class="flex justify-between">
|
|
323
361
|
<span>Taxes</span><span>${taxes.toFixed(2)}</span>
|
|
324
362
|
</div>
|
|
363
|
+
{#if giftCardApplied}
|
|
364
|
+
<div class="flex justify-between text-green-600 dark:text-green-500">
|
|
365
|
+
<span>Gift Card Applied</span>
|
|
366
|
+
<span>-${giftCardAmountDisplay}</span>
|
|
367
|
+
</div>
|
|
368
|
+
{#if giftCardRemainingBalance && parseFloat(giftCardRemainingBalance) > 0}
|
|
369
|
+
<div class="flex justify-between text-gray-500 dark:text-gray-400 text-xs">
|
|
370
|
+
<span>Gift card balance after order</span>
|
|
371
|
+
<span>${giftCardRemainingBalance}</span>
|
|
372
|
+
</div>
|
|
373
|
+
{/if}
|
|
374
|
+
{/if}
|
|
325
375
|
</div>
|
|
326
376
|
|
|
327
|
-
|
|
328
|
-
<
|
|
329
|
-
|
|
377
|
+
{#if giftCardApplied?.paymentType === 'gift_card_only'}
|
|
378
|
+
<div class="flex justify-between py-5 border-t border-gray-200 dark:border-gray-600">
|
|
379
|
+
<span class="font-semibold text-gray-900 dark:text-white">Amount Due</span>
|
|
380
|
+
<span class="font-bold text-green-600 dark:text-green-400">$0.00</span>
|
|
381
|
+
</div>
|
|
382
|
+
<p class="text-xs text-gray-500 dark:text-gray-400 text-center -mt-2 mb-2">
|
|
383
|
+
Fully covered by gift card
|
|
384
|
+
</p>
|
|
385
|
+
{:else}
|
|
386
|
+
<div class="flex justify-between {typography.h3} py-5 border-t border-gray-200 dark:border-gray-600">
|
|
387
|
+
<span>Total</span><span>${total.toFixed(2)}</span>
|
|
388
|
+
</div>
|
|
389
|
+
{/if}
|
|
330
390
|
</div>
|
|
331
391
|
</div>
|
|
332
392
|
{/if}
|
|
@@ -18,6 +18,7 @@ declare const OrderSummary: import("svelte").Component<{
|
|
|
18
18
|
elements?: any;
|
|
19
19
|
venueServiceCharge?: Record<string, any>;
|
|
20
20
|
onPriceUpdate: any;
|
|
21
|
+
giftCardApplied?: any;
|
|
21
22
|
}, {}, "">;
|
|
22
23
|
type $$ComponentProps = {
|
|
23
24
|
loading?: boolean;
|
|
@@ -34,5 +35,6 @@ type $$ComponentProps = {
|
|
|
34
35
|
elements?: any;
|
|
35
36
|
venueServiceCharge?: Record<string, any>;
|
|
36
37
|
onPriceUpdate: any;
|
|
38
|
+
giftCardApplied?: any;
|
|
37
39
|
};
|
|
38
40
|
//# sourceMappingURL=OrderSummary.svelte.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OrderSummary.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/calendar/OrderSummary/OrderSummary.svelte.js"],"names":[],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"OrderSummary.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/calendar/OrderSummary/OrderSummary.svelte.js"],"names":[],"mappings":";;;;;AAgZA;cAhY+B,OAAO;iBAAe,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;sBAAoB,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;mBAAiB,GAAG,EAAE;qBAAmB,GAAG;eAAa,OAAO;cAAY,MAAM;mBAAiB,OAAO;oBAAkB,MAAM;uBAAqB,GAAG;sBAAoB,GAAG;eAAa,GAAG;yBAAuB,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;mBAAiB,GAAG;sBAAoB,GAAG;WAgY1U;wBAhYxC;IAAE,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAAC,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAAC,YAAY,CAAC,EAAE,GAAG,EAAE,CAAC;IAAC,cAAc,CAAC,EAAE,GAAG,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,OAAO,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAAC,gBAAgB,CAAC,EAAE,GAAG,CAAC;IAAC,eAAe,CAAC,EAAE,GAAG,CAAC;IAAC,QAAQ,CAAC,EAAE,GAAG,CAAC;IAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAAC,aAAa,EAAE,GAAG,CAAC;IAAC,eAAe,CAAC,EAAE,GAAG,CAAA;CAAE"}
|
package/dist/index.spec.js
CHANGED
|
@@ -353,7 +353,7 @@ describe('Tree-Shaking Structure', () => {
|
|
|
353
353
|
// patterns/index.js should use export * from subdirs
|
|
354
354
|
const patternsContent = readFile('./patterns/index.js');
|
|
355
355
|
const patternsReExports = (patternsContent.match(/export \* from/g) || []).length;
|
|
356
|
-
expect(patternsReExports).toBe(
|
|
356
|
+
expect(patternsReExports).toBe(6); // chat, forms, navigation, page, data, layout
|
|
357
357
|
});
|
|
358
358
|
|
|
359
359
|
it('leaf indexes export components individually', () => {
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* ChatActivityNotice - Centered notice for silent/background activity
|
|
4
|
+
*
|
|
5
|
+
* Displays activity that happened without notification (e.g., admin status changes)
|
|
6
|
+
* in a subtle centered format with decorative lines.
|
|
7
|
+
*/
|
|
8
|
+
import type { Snippet } from 'svelte';
|
|
9
|
+
import { classNames } from '../../utils/utils.js';
|
|
10
|
+
|
|
11
|
+
interface Props {
|
|
12
|
+
/** Actor name who performed the action */
|
|
13
|
+
actorName?: string;
|
|
14
|
+
/** Timestamp of the action */
|
|
15
|
+
timestamp?: string;
|
|
16
|
+
/** Additional CSS classes */
|
|
17
|
+
className?: string;
|
|
18
|
+
/** Content to display (status changes, etc.) */
|
|
19
|
+
children?: Snippet;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
let {
|
|
23
|
+
actorName,
|
|
24
|
+
timestamp,
|
|
25
|
+
className = '',
|
|
26
|
+
children,
|
|
27
|
+
}: Props = $props();
|
|
28
|
+
</script>
|
|
29
|
+
|
|
30
|
+
<div class={classNames('flex items-center justify-center gap-3 py-3', className)}>
|
|
31
|
+
<div class="h-px bg-gray-200 dark:bg-gray-700 w-12"></div>
|
|
32
|
+
<div class="flex flex-col items-center gap-1">
|
|
33
|
+
{@render children?.()}
|
|
34
|
+
{#if actorName || timestamp}
|
|
35
|
+
<span class="text-[10px] text-gray-400">
|
|
36
|
+
{#if actorName}{actorName}{/if}{#if actorName && timestamp} · {/if}{#if timestamp}{timestamp}{/if}
|
|
37
|
+
</span>
|
|
38
|
+
{/if}
|
|
39
|
+
</div>
|
|
40
|
+
<div class="h-px bg-gray-200 dark:bg-gray-700 w-12"></div>
|
|
41
|
+
</div>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ChatActivityNotice - Centered notice for silent/background activity
|
|
3
|
+
*
|
|
4
|
+
* Displays activity that happened without notification (e.g., admin status changes)
|
|
5
|
+
* in a subtle centered format with decorative lines.
|
|
6
|
+
*/
|
|
7
|
+
import type { Snippet } from 'svelte';
|
|
8
|
+
interface Props {
|
|
9
|
+
/** Actor name who performed the action */
|
|
10
|
+
actorName?: string;
|
|
11
|
+
/** Timestamp of the action */
|
|
12
|
+
timestamp?: string;
|
|
13
|
+
/** Additional CSS classes */
|
|
14
|
+
className?: string;
|
|
15
|
+
/** Content to display (status changes, etc.) */
|
|
16
|
+
children?: Snippet;
|
|
17
|
+
}
|
|
18
|
+
declare const ChatActivityNotice: import("svelte").Component<Props, {}, "">;
|
|
19
|
+
type ChatActivityNotice = ReturnType<typeof ChatActivityNotice>;
|
|
20
|
+
export default ChatActivityNotice;
|
|
21
|
+
//# sourceMappingURL=ChatActivityNotice.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChatActivityNotice.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/patterns/chat/ChatActivityNotice.svelte.ts"],"names":[],"mappings":"AAGA;;;;;KAKK;AACL,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAIpC,UAAU,KAAK;IACb,0CAA0C;IAC1C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,8BAA8B;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,6BAA6B;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gDAAgD;IAChD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AA8BH,QAAA,MAAM,kBAAkB,2CAAwC,CAAC;AACjE,KAAK,kBAAkB,GAAG,UAAU,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAChE,eAAe,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* ChatBubble - Message bubble for chat interfaces
|
|
4
|
+
*
|
|
5
|
+
* Displays inbound (left) or outbound (right) messages with optional
|
|
6
|
+
* error state, timestamp, and sender name.
|
|
7
|
+
*/
|
|
8
|
+
import type { Snippet } from 'svelte';
|
|
9
|
+
import { classNames } from '../../utils/utils.js';
|
|
10
|
+
import Renew from 'carbon-icons-svelte/lib/Renew.svelte';
|
|
11
|
+
|
|
12
|
+
interface Props {
|
|
13
|
+
/** Message direction - inbound (from other) or outbound (from us) */
|
|
14
|
+
direction?: 'inbound' | 'outbound';
|
|
15
|
+
/** Sender name (shown for inbound messages) */
|
|
16
|
+
senderName?: string;
|
|
17
|
+
/** Timestamp to display */
|
|
18
|
+
timestamp?: string;
|
|
19
|
+
/** Whether delivery failed */
|
|
20
|
+
failed?: boolean;
|
|
21
|
+
/** Error message when failed */
|
|
22
|
+
errorMessage?: string;
|
|
23
|
+
/** Callback when retry is clicked */
|
|
24
|
+
onretry?: () => void;
|
|
25
|
+
/** Additional CSS classes for the bubble */
|
|
26
|
+
className?: string;
|
|
27
|
+
/** Avatar snippet (for inbound messages) */
|
|
28
|
+
avatar?: Snippet;
|
|
29
|
+
/** Message content */
|
|
30
|
+
children?: Snippet;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
let {
|
|
34
|
+
direction = 'inbound',
|
|
35
|
+
senderName,
|
|
36
|
+
timestamp,
|
|
37
|
+
failed = false,
|
|
38
|
+
errorMessage,
|
|
39
|
+
onretry,
|
|
40
|
+
className = '',
|
|
41
|
+
avatar,
|
|
42
|
+
children,
|
|
43
|
+
}: Props = $props();
|
|
44
|
+
|
|
45
|
+
let isOutbound = $derived(direction === 'outbound');
|
|
46
|
+
|
|
47
|
+
let bubbleClasses = $derived(
|
|
48
|
+
classNames(
|
|
49
|
+
'px-4 py-2.5 rounded-2xl text-sm',
|
|
50
|
+
isOutbound
|
|
51
|
+
? 'bg-blue-600 text-white rounded-br-sm'
|
|
52
|
+
: 'bg-gray-100 dark:bg-gray-800 text-gray-900 dark:text-white rounded-bl-sm',
|
|
53
|
+
className
|
|
54
|
+
)
|
|
55
|
+
);
|
|
56
|
+
</script>
|
|
57
|
+
|
|
58
|
+
<div class="flex {isOutbound ? 'justify-end' : 'justify-start'}">
|
|
59
|
+
<div class="flex items-end gap-2 max-w-[75%] {isOutbound ? 'flex-row-reverse' : ''}">
|
|
60
|
+
{#if !isOutbound && avatar}
|
|
61
|
+
{@render avatar()}
|
|
62
|
+
{/if}
|
|
63
|
+
<div class="flex flex-col {isOutbound ? 'items-end' : 'items-start'}">
|
|
64
|
+
{#if !isOutbound && senderName}
|
|
65
|
+
<span class="text-xs text-gray-500 mb-1 px-2">{senderName}</span>
|
|
66
|
+
{/if}
|
|
67
|
+
<div class="flex items-center gap-2 {isOutbound ? 'flex-row-reverse' : ''}">
|
|
68
|
+
<div class={bubbleClasses}>
|
|
69
|
+
{@render children?.()}
|
|
70
|
+
</div>
|
|
71
|
+
{#if failed}
|
|
72
|
+
<div class="flex items-center justify-center w-5 h-5 bg-red-500 rounded-full shrink-0">
|
|
73
|
+
<span class="text-white text-xs font-bold leading-none">!</span>
|
|
74
|
+
</div>
|
|
75
|
+
{/if}
|
|
76
|
+
</div>
|
|
77
|
+
{#if failed && errorMessage}
|
|
78
|
+
<div class="flex items-center gap-1 mt-0.5 px-2">
|
|
79
|
+
<span class="text-[9px] text-red-400">{errorMessage}</span>
|
|
80
|
+
{#if onretry}
|
|
81
|
+
<button
|
|
82
|
+
class="text-[9px] text-red-400 hover:text-red-500 flex items-center gap-0.5 opacity-75 hover:opacity-100"
|
|
83
|
+
onclick={onretry}
|
|
84
|
+
>
|
|
85
|
+
<Renew class="w-2 h-2" />
|
|
86
|
+
retry
|
|
87
|
+
</button>
|
|
88
|
+
{/if}
|
|
89
|
+
</div>
|
|
90
|
+
{:else if timestamp}
|
|
91
|
+
<span class="text-[10px] text-gray-400 mt-0.5 px-2">{timestamp}</span>
|
|
92
|
+
{/if}
|
|
93
|
+
</div>
|
|
94
|
+
</div>
|
|
95
|
+
</div>
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ChatBubble - Message bubble for chat interfaces
|
|
3
|
+
*
|
|
4
|
+
* Displays inbound (left) or outbound (right) messages with optional
|
|
5
|
+
* error state, timestamp, and sender name.
|
|
6
|
+
*/
|
|
7
|
+
import type { Snippet } from 'svelte';
|
|
8
|
+
interface Props {
|
|
9
|
+
/** Message direction - inbound (from other) or outbound (from us) */
|
|
10
|
+
direction?: 'inbound' | 'outbound';
|
|
11
|
+
/** Sender name (shown for inbound messages) */
|
|
12
|
+
senderName?: string;
|
|
13
|
+
/** Timestamp to display */
|
|
14
|
+
timestamp?: string;
|
|
15
|
+
/** Whether delivery failed */
|
|
16
|
+
failed?: boolean;
|
|
17
|
+
/** Error message when failed */
|
|
18
|
+
errorMessage?: string;
|
|
19
|
+
/** Callback when retry is clicked */
|
|
20
|
+
onretry?: () => void;
|
|
21
|
+
/** Additional CSS classes for the bubble */
|
|
22
|
+
className?: string;
|
|
23
|
+
/** Avatar snippet (for inbound messages) */
|
|
24
|
+
avatar?: Snippet;
|
|
25
|
+
/** Message content */
|
|
26
|
+
children?: Snippet;
|
|
27
|
+
}
|
|
28
|
+
declare const ChatBubble: import("svelte").Component<Props, {}, "">;
|
|
29
|
+
type ChatBubble = ReturnType<typeof ChatBubble>;
|
|
30
|
+
export default ChatBubble;
|
|
31
|
+
//# sourceMappingURL=ChatBubble.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChatBubble.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/patterns/chat/ChatBubble.svelte.ts"],"names":[],"mappings":"AAGA;;;;;KAKK;AACL,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAKpC,UAAU,KAAK;IACb,qEAAqE;IACrE,SAAS,CAAC,EAAE,SAAS,GAAG,UAAU,CAAC;IACnC,+CAA+C;IAC/C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,2BAA2B;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,8BAA8B;IAC9B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,gCAAgC;IAChC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,qCAAqC;IACrC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,4CAA4C;IAC5C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,4CAA4C;IAC5C,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,sBAAsB;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAuEH,QAAA,MAAM,UAAU,2CAAwC,CAAC;AACzD,KAAK,UAAU,GAAG,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC;AAChD,eAAe,UAAU,CAAC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* ChatContainer - Layout wrapper for chat interfaces
|
|
4
|
+
*
|
|
5
|
+
* Provides a flex column layout with optional header, scrollable message area,
|
|
6
|
+
* and fixed footer for message input.
|
|
7
|
+
*/
|
|
8
|
+
import type { Snippet } from 'svelte';
|
|
9
|
+
import { classNames } from '../../utils/utils.js';
|
|
10
|
+
|
|
11
|
+
interface Props {
|
|
12
|
+
/** Additional CSS classes for the container */
|
|
13
|
+
className?: string;
|
|
14
|
+
/** Header content (title, subtitle, etc.) */
|
|
15
|
+
header?: Snippet;
|
|
16
|
+
/** Footer content (message input, actions) */
|
|
17
|
+
footer?: Snippet;
|
|
18
|
+
/** Main scrollable content */
|
|
19
|
+
children?: Snippet;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
let {
|
|
23
|
+
className = '',
|
|
24
|
+
header,
|
|
25
|
+
footer,
|
|
26
|
+
children,
|
|
27
|
+
}: Props = $props();
|
|
28
|
+
</script>
|
|
29
|
+
|
|
30
|
+
<div class={classNames('flex flex-col h-full bg-white dark:bg-gray-900', className)}>
|
|
31
|
+
{#if header}
|
|
32
|
+
<div class="px-4 py-3 border-b border-gray-200 dark:border-gray-700 shrink-0">
|
|
33
|
+
{@render header()}
|
|
34
|
+
</div>
|
|
35
|
+
{/if}
|
|
36
|
+
|
|
37
|
+
<div class="flex-1 overflow-y-auto px-4 py-4 space-y-3">
|
|
38
|
+
{@render children?.()}
|
|
39
|
+
</div>
|
|
40
|
+
|
|
41
|
+
{#if footer}
|
|
42
|
+
<div class="px-4 py-3 border-t border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-800 shrink-0">
|
|
43
|
+
{@render footer()}
|
|
44
|
+
</div>
|
|
45
|
+
{/if}
|
|
46
|
+
</div>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ChatContainer - Layout wrapper for chat interfaces
|
|
3
|
+
*
|
|
4
|
+
* Provides a flex column layout with optional header, scrollable message area,
|
|
5
|
+
* and fixed footer for message input.
|
|
6
|
+
*/
|
|
7
|
+
import type { Snippet } from 'svelte';
|
|
8
|
+
interface Props {
|
|
9
|
+
/** Additional CSS classes for the container */
|
|
10
|
+
className?: string;
|
|
11
|
+
/** Header content (title, subtitle, etc.) */
|
|
12
|
+
header?: Snippet;
|
|
13
|
+
/** Footer content (message input, actions) */
|
|
14
|
+
footer?: Snippet;
|
|
15
|
+
/** Main scrollable content */
|
|
16
|
+
children?: Snippet;
|
|
17
|
+
}
|
|
18
|
+
declare const ChatContainer: import("svelte").Component<Props, {}, "">;
|
|
19
|
+
type ChatContainer = ReturnType<typeof ChatContainer>;
|
|
20
|
+
export default ChatContainer;
|
|
21
|
+
//# sourceMappingURL=ChatContainer.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChatContainer.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/patterns/chat/ChatContainer.svelte.ts"],"names":[],"mappings":"AAGA;;;;;KAKK;AACL,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAIpC,UAAU,KAAK;IACb,+CAA+C;IAC/C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,6CAA6C;IAC7C,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,8CAA8C;IAC9C,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,8BAA8B;IAC9B,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAmCH,QAAA,MAAM,aAAa,2CAAwC,CAAC;AAC5D,KAAK,aAAa,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC;AACtD,eAAe,aAAa,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* ChatDateDivider - Date separator for chat messages
|
|
4
|
+
*
|
|
5
|
+
* Displays a centered date label (Today, Yesterday, or formatted date)
|
|
6
|
+
* to separate messages by day.
|
|
7
|
+
*/
|
|
8
|
+
import { classNames } from '../../utils/utils.js';
|
|
9
|
+
|
|
10
|
+
interface Props {
|
|
11
|
+
/** Date label to display (e.g., "Today", "Yesterday", "Monday, Jan 15, 2024") */
|
|
12
|
+
label: string;
|
|
13
|
+
/** Additional CSS classes */
|
|
14
|
+
className?: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
let {
|
|
18
|
+
label,
|
|
19
|
+
className = '',
|
|
20
|
+
}: Props = $props();
|
|
21
|
+
</script>
|
|
22
|
+
|
|
23
|
+
<div class={classNames('text-center py-2', className)}>
|
|
24
|
+
<span class="text-xs font-semibold text-gray-500 dark:text-gray-400 bg-gray-100 dark:bg-gray-800 px-3 py-1 rounded-full">
|
|
25
|
+
{label}
|
|
26
|
+
</span>
|
|
27
|
+
</div>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
interface Props {
|
|
2
|
+
/** Date label to display (e.g., "Today", "Yesterday", "Monday, Jan 15, 2024") */
|
|
3
|
+
label: string;
|
|
4
|
+
/** Additional CSS classes */
|
|
5
|
+
className?: string;
|
|
6
|
+
}
|
|
7
|
+
declare const ChatDateDivider: import("svelte").Component<Props, {}, "">;
|
|
8
|
+
type ChatDateDivider = ReturnType<typeof ChatDateDivider>;
|
|
9
|
+
export default ChatDateDivider;
|
|
10
|
+
//# sourceMappingURL=ChatDateDivider.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChatDateDivider.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/patterns/chat/ChatDateDivider.svelte.ts"],"names":[],"mappings":"AAYE,UAAU,KAAK;IACb,iFAAiF;IACjF,KAAK,EAAE,MAAM,CAAC;IACd,6BAA6B;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAoBH,QAAA,MAAM,eAAe,2CAAwC,CAAC;AAC9D,KAAK,eAAe,GAAG,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC;AAC1D,eAAe,eAAe,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* ChatInvitationBubble - Invitation notification bubble
|
|
4
|
+
*
|
|
5
|
+
* Shows "Invited {performerName}" with send icon in a blue bubble.
|
|
6
|
+
*/
|
|
7
|
+
import { classNames } from '../../utils/utils.js';
|
|
8
|
+
import SendAltFilled from 'carbon-icons-svelte/lib/SendAltFilled.svelte';
|
|
9
|
+
|
|
10
|
+
interface Props {
|
|
11
|
+
/** Name of the performer who was invited */
|
|
12
|
+
performerName: string;
|
|
13
|
+
/** Whether this is outbound (right side) */
|
|
14
|
+
outbound?: boolean;
|
|
15
|
+
/** Additional CSS classes */
|
|
16
|
+
className?: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
let {
|
|
20
|
+
performerName,
|
|
21
|
+
outbound = true,
|
|
22
|
+
className = '',
|
|
23
|
+
}: Props = $props();
|
|
24
|
+
|
|
25
|
+
let bubbleClasses = $derived(
|
|
26
|
+
classNames(
|
|
27
|
+
'px-4 py-2.5 rounded-2xl text-sm bg-blue-600 text-white flex items-center gap-1.5',
|
|
28
|
+
outbound ? 'rounded-br-sm' : 'rounded-bl-sm',
|
|
29
|
+
className
|
|
30
|
+
)
|
|
31
|
+
);
|
|
32
|
+
</script>
|
|
33
|
+
|
|
34
|
+
<div class={bubbleClasses}>
|
|
35
|
+
<SendAltFilled class="w-4 h-4" />
|
|
36
|
+
Invited {performerName}
|
|
37
|
+
</div>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
interface Props {
|
|
2
|
+
/** Name of the performer who was invited */
|
|
3
|
+
performerName: string;
|
|
4
|
+
/** Whether this is outbound (right side) */
|
|
5
|
+
outbound?: boolean;
|
|
6
|
+
/** Additional CSS classes */
|
|
7
|
+
className?: string;
|
|
8
|
+
}
|
|
9
|
+
declare const ChatInvitationBubble: import("svelte").Component<Props, {}, "">;
|
|
10
|
+
type ChatInvitationBubble = ReturnType<typeof ChatInvitationBubble>;
|
|
11
|
+
export default ChatInvitationBubble;
|
|
12
|
+
//# sourceMappingURL=ChatInvitationBubble.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChatInvitationBubble.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/patterns/chat/ChatInvitationBubble.svelte.ts"],"names":[],"mappings":"AAYE,UAAU,KAAK;IACb,4CAA4C;IAC5C,aAAa,EAAE,MAAM,CAAC;IACtB,4CAA4C;IAC5C,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,6BAA6B;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA6BH,QAAA,MAAM,oBAAoB,2CAAwC,CAAC;AACnE,KAAK,oBAAoB,GAAG,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAC;AACpE,eAAe,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* ChatInvitationNotice - Inline invitation notice
|
|
4
|
+
*
|
|
5
|
+
* Shows "Invited {performerName}" with icon for activity notices.
|
|
6
|
+
* Smaller/subtler than ChatInvitationBubble.
|
|
7
|
+
*/
|
|
8
|
+
import { classNames } from '../../utils/utils.js';
|
|
9
|
+
import SendAltFilled from 'carbon-icons-svelte/lib/SendAltFilled.svelte';
|
|
10
|
+
|
|
11
|
+
interface Props {
|
|
12
|
+
/** Name of the performer who was invited */
|
|
13
|
+
performerName: string;
|
|
14
|
+
/** Additional CSS classes */
|
|
15
|
+
className?: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
let {
|
|
19
|
+
performerName,
|
|
20
|
+
className = '',
|
|
21
|
+
}: Props = $props();
|
|
22
|
+
</script>
|
|
23
|
+
|
|
24
|
+
<span class={classNames('text-xs font-medium text-blue-600 flex items-center gap-1', className)}>
|
|
25
|
+
<SendAltFilled class="w-3 h-3" />
|
|
26
|
+
Invited {performerName}
|
|
27
|
+
</span>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
interface Props {
|
|
2
|
+
/** Name of the performer who was invited */
|
|
3
|
+
performerName: string;
|
|
4
|
+
/** Additional CSS classes */
|
|
5
|
+
className?: string;
|
|
6
|
+
}
|
|
7
|
+
declare const ChatInvitationNotice: import("svelte").Component<Props, {}, "">;
|
|
8
|
+
type ChatInvitationNotice = ReturnType<typeof ChatInvitationNotice>;
|
|
9
|
+
export default ChatInvitationNotice;
|
|
10
|
+
//# sourceMappingURL=ChatInvitationNotice.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChatInvitationNotice.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/patterns/chat/ChatInvitationNotice.svelte.ts"],"names":[],"mappings":"AAaE,UAAU,KAAK;IACb,4CAA4C;IAC5C,aAAa,EAAE,MAAM,CAAC;IACtB,6BAA6B;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAoBH,QAAA,MAAM,oBAAoB,2CAAwC,CAAC;AACnE,KAAK,oBAAoB,GAAG,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAC;AACpE,eAAe,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* ChatMessageGroup - Groups multiple items from the same sender
|
|
4
|
+
*
|
|
5
|
+
* Wraps avatar, sender name, multiple content items, and timestamp
|
|
6
|
+
* for when a user sends multiple things at once (status change + message).
|
|
7
|
+
*/
|
|
8
|
+
import type { Snippet } from 'svelte';
|
|
9
|
+
import { classNames } from '../../utils/utils.js';
|
|
10
|
+
|
|
11
|
+
interface Props {
|
|
12
|
+
/** Sender name */
|
|
13
|
+
senderName?: string;
|
|
14
|
+
/** Timestamp to display */
|
|
15
|
+
timestamp?: string;
|
|
16
|
+
/** Direction - inbound (left) or outbound (right) */
|
|
17
|
+
direction?: 'inbound' | 'outbound';
|
|
18
|
+
/** Additional CSS classes */
|
|
19
|
+
className?: string;
|
|
20
|
+
/** Avatar slot */
|
|
21
|
+
avatar?: Snippet;
|
|
22
|
+
/** Content items (status badges, messages, etc.) */
|
|
23
|
+
children?: Snippet;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
let {
|
|
27
|
+
senderName,
|
|
28
|
+
timestamp,
|
|
29
|
+
direction = 'inbound',
|
|
30
|
+
className = '',
|
|
31
|
+
avatar,
|
|
32
|
+
children,
|
|
33
|
+
}: Props = $props();
|
|
34
|
+
|
|
35
|
+
let isOutbound = $derived(direction === 'outbound');
|
|
36
|
+
</script>
|
|
37
|
+
|
|
38
|
+
<div class={classNames('flex', isOutbound ? 'justify-end' : 'justify-start', className)}>
|
|
39
|
+
<div class="flex items-end gap-2 max-w-[75%] {isOutbound ? 'flex-row-reverse' : ''}">
|
|
40
|
+
{#if avatar && !isOutbound}
|
|
41
|
+
{@render avatar()}
|
|
42
|
+
{/if}
|
|
43
|
+
<div class="flex flex-col {isOutbound ? 'items-end' : 'items-start'}">
|
|
44
|
+
{#if senderName && !isOutbound}
|
|
45
|
+
<span class="text-xs text-gray-500 mb-1 px-2">{senderName}</span>
|
|
46
|
+
{/if}
|
|
47
|
+
<div class="flex flex-col {isOutbound ? 'items-end' : 'items-start'} gap-1">
|
|
48
|
+
{@render children?.()}
|
|
49
|
+
</div>
|
|
50
|
+
{#if timestamp}
|
|
51
|
+
<span class="text-[10px] text-gray-400 mt-0.5 px-2">
|
|
52
|
+
{#if isOutbound && senderName}{senderName} · {/if}{timestamp}
|
|
53
|
+
</span>
|
|
54
|
+
{/if}
|
|
55
|
+
</div>
|
|
56
|
+
</div>
|
|
57
|
+
</div>
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ChatMessageGroup - Groups multiple items from the same sender
|
|
3
|
+
*
|
|
4
|
+
* Wraps avatar, sender name, multiple content items, and timestamp
|
|
5
|
+
* for when a user sends multiple things at once (status change + message).
|
|
6
|
+
*/
|
|
7
|
+
import type { Snippet } from 'svelte';
|
|
8
|
+
interface Props {
|
|
9
|
+
/** Sender name */
|
|
10
|
+
senderName?: string;
|
|
11
|
+
/** Timestamp to display */
|
|
12
|
+
timestamp?: string;
|
|
13
|
+
/** Direction - inbound (left) or outbound (right) */
|
|
14
|
+
direction?: 'inbound' | 'outbound';
|
|
15
|
+
/** Additional CSS classes */
|
|
16
|
+
className?: string;
|
|
17
|
+
/** Avatar slot */
|
|
18
|
+
avatar?: Snippet;
|
|
19
|
+
/** Content items (status badges, messages, etc.) */
|
|
20
|
+
children?: Snippet;
|
|
21
|
+
}
|
|
22
|
+
declare const ChatMessageGroup: import("svelte").Component<Props, {}, "">;
|
|
23
|
+
type ChatMessageGroup = ReturnType<typeof ChatMessageGroup>;
|
|
24
|
+
export default ChatMessageGroup;
|
|
25
|
+
//# sourceMappingURL=ChatMessageGroup.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChatMessageGroup.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/patterns/chat/ChatMessageGroup.svelte.ts"],"names":[],"mappings":"AAGA;;;;;KAKK;AACL,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAIpC,UAAU,KAAK;IACb,kBAAkB;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,2BAA2B;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qDAAqD;IACrD,SAAS,CAAC,EAAE,SAAS,GAAG,UAAU,CAAC;IACnC,6BAA6B;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kBAAkB;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,oDAAoD;IACpD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AA0CH,QAAA,MAAM,gBAAgB,2CAAwC,CAAC;AAC/D,KAAK,gBAAgB,GAAG,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAC5D,eAAe,gBAAgB,CAAC"}
|