@getmicdrop/svelte-components 5.17.1 → 5.17.4
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/Calendar/MiniMonthCalendar.svelte +5 -7
- package/dist/calendar/Calendar/MiniMonthCalendar.svelte.d.ts.map +1 -1
- package/dist/calendar/MonthSwitcher/MonthSwitcher.svelte +2 -3
- package/dist/calendar/MonthSwitcher/MonthSwitcher.svelte.d.ts.map +1 -1
- package/dist/calendar/PublicCard/PublicCard.svelte +23 -14
- package/dist/calendar/PublicCard/PublicCard.svelte.d.ts.map +1 -1
- package/dist/calendar/ShowCard/ShowCard.spec.js +1 -7
- package/dist/calendar/ShowCard/ShowCard.svelte +10 -1
- package/dist/calendar/ShowCard/ShowCard.svelte.d.ts.map +1 -1
- package/dist/calendar/ShowTimeCard/ShowTimeCard.svelte +11 -0
- package/dist/calendar/ShowTimeCard/ShowTimeCard.svelte.d.ts +2 -0
- package/dist/calendar/ShowTimeCard/ShowTimeCard.svelte.d.ts.map +1 -1
- package/dist/components/Heading.spec.d.ts +2 -0
- package/dist/components/Heading.spec.d.ts.map +1 -0
- package/dist/components/Heading.spec.js +89 -0
- package/dist/components/Layout/__tests__/AppShell.test.js +140 -0
- package/dist/components/Text.spec.d.ts +2 -0
- package/dist/components/Text.spec.d.ts.map +1 -0
- package/dist/components/Text.spec.js +89 -0
- package/dist/config.d.ts +102 -0
- package/dist/config.js +147 -1
- package/dist/datetime/README.md +323 -0
- package/dist/forms/createFormStore.svelte.spec.d.ts +2 -0
- package/dist/forms/createFormStore.svelte.spec.d.ts.map +1 -0
- package/dist/forms/createFormStore.svelte.spec.js +387 -0
- package/dist/messages.d.ts +43 -0
- package/dist/messages.d.ts.map +1 -0
- package/dist/messages.js +57 -0
- package/dist/patterns/chat/ChatActivityNotice.spec.d.ts +2 -0
- package/dist/patterns/chat/ChatActivityNotice.spec.d.ts.map +1 -0
- package/dist/patterns/chat/ChatActivityNotice.spec.js +59 -0
- package/dist/patterns/chat/ChatBubble.spec.d.ts +2 -0
- package/dist/patterns/chat/ChatBubble.spec.d.ts.map +1 -0
- package/dist/patterns/chat/ChatBubble.spec.js +91 -0
- package/dist/patterns/chat/ChatContainer.spec.d.ts +2 -0
- package/dist/patterns/chat/ChatContainer.spec.d.ts.map +1 -0
- package/dist/patterns/chat/ChatContainer.spec.js +30 -0
- package/dist/patterns/chat/ChatDateDivider.spec.d.ts +2 -0
- package/dist/patterns/chat/ChatDateDivider.spec.d.ts.map +1 -0
- package/dist/patterns/chat/ChatDateDivider.spec.js +30 -0
- package/dist/patterns/chat/ChatInvitationBubble.spec.d.ts +2 -0
- package/dist/patterns/chat/ChatInvitationBubble.spec.d.ts.map +1 -0
- package/dist/patterns/chat/ChatInvitationBubble.spec.js +46 -0
- package/dist/patterns/chat/ChatInvitationNotice.spec.d.ts +2 -0
- package/dist/patterns/chat/ChatInvitationNotice.spec.d.ts.map +1 -0
- package/dist/patterns/chat/ChatInvitationNotice.spec.js +32 -0
- package/dist/patterns/chat/ChatMessageGroup.spec.d.ts +2 -0
- package/dist/patterns/chat/ChatMessageGroup.spec.d.ts.map +1 -0
- package/dist/patterns/chat/ChatMessageGroup.spec.js +58 -0
- package/dist/patterns/chat/ChatSlotUpdate.spec.d.ts +2 -0
- package/dist/patterns/chat/ChatSlotUpdate.spec.d.ts.map +1 -0
- package/dist/patterns/chat/ChatSlotUpdate.spec.js +65 -0
- package/dist/patterns/chat/ChatStatusBadge.spec.d.ts +2 -0
- package/dist/patterns/chat/ChatStatusBadge.spec.d.ts.map +1 -0
- package/dist/patterns/chat/ChatStatusBadge.spec.js +79 -0
- package/dist/patterns/chat/ChatStatusTransition.spec.d.ts +2 -0
- package/dist/patterns/chat/ChatStatusTransition.spec.d.ts.map +1 -0
- package/dist/patterns/chat/ChatStatusTransition.spec.js +81 -0
- package/dist/patterns/chat/ChatTextBubble.spec.d.ts +2 -0
- package/dist/patterns/chat/ChatTextBubble.spec.d.ts.map +1 -0
- package/dist/patterns/chat/ChatTextBubble.spec.js +35 -0
- package/dist/patterns/data/DataTable.spec.js +61 -0
- package/dist/patterns/forms/FormGrid.spec.js +34 -0
- package/dist/patterns/layout/Sidebar.spec.js +240 -1
- package/dist/patterns/layout/SidebarTestWrapper.svelte +34 -0
- package/dist/patterns/layout/SidebarTestWrapper.svelte.d.ts +23 -0
- package/dist/patterns/layout/SidebarTestWrapper.svelte.d.ts.map +1 -0
- package/dist/patterns/navigation/Header.spec.js +123 -0
- package/dist/primitives/Accordion/Accordion.spec.js +112 -2
- package/dist/primitives/Accordion/AccordionToggleWrapper.test.svelte +28 -0
- package/dist/primitives/Accordion/AccordionToggleWrapper.test.svelte.d.ts +7 -0
- package/dist/primitives/Accordion/AccordionToggleWrapper.test.svelte.d.ts.map +1 -0
- package/dist/primitives/Avatar/Avatar.spec.js +23 -0
- package/dist/primitives/BottomSheet/BottomSheet.spec.js +102 -0
- package/dist/primitives/BottomSheet/BottomSheetWithActions.test.svelte +20 -0
- package/dist/primitives/BottomSheet/BottomSheetWithActions.test.svelte.d.ts +10 -0
- package/dist/primitives/BottomSheet/BottomSheetWithActions.test.svelte.d.ts.map +1 -0
- package/dist/primitives/Button/ButtonGroup.spec.d.ts +2 -0
- package/dist/primitives/Button/ButtonGroup.spec.d.ts.map +1 -0
- package/dist/primitives/Button/ButtonGroup.spec.js +44 -0
- package/dist/primitives/Checkbox/Checkbox.spec.js +32 -0
- package/dist/primitives/Drawer/Drawer.spec.js +437 -0
- package/dist/primitives/Drawer/DrawerTestWrapper.svelte +86 -0
- package/dist/primitives/Drawer/DrawerTestWrapper.svelte.d.ts +26 -0
- package/dist/primitives/Drawer/DrawerTestWrapper.svelte.d.ts.map +1 -0
- package/dist/primitives/Dropdown/Dropdown.spec.js +116 -0
- package/dist/primitives/Dropdown/DropdownDivider.spec.d.ts +2 -0
- package/dist/primitives/Dropdown/DropdownDivider.spec.d.ts.map +1 -0
- package/dist/primitives/Dropdown/DropdownDivider.spec.js +30 -0
- package/dist/primitives/Dropdown/DropdownItem.spec.js +155 -1
- package/dist/primitives/Dropdown/DropdownItemTestWrapper.svelte +43 -0
- package/dist/primitives/Dropdown/DropdownItemTestWrapper.svelte.d.ts +17 -0
- package/dist/primitives/Dropdown/DropdownItemTestWrapper.svelte.d.ts.map +1 -0
- package/dist/primitives/Helper/Helper.spec.d.ts +2 -0
- package/dist/primitives/Helper/Helper.spec.d.ts.map +1 -0
- package/dist/primitives/Helper/Helper.spec.js +57 -0
- package/dist/primitives/Input/Input.spec.js +664 -0
- package/dist/primitives/Input/Input.svelte +18 -10
- package/dist/primitives/Input/Input.svelte.d.ts.map +1 -1
- package/dist/primitives/Input/Select.spec.js +414 -0
- package/dist/primitives/Label/Label.spec.js +9 -0
- package/dist/primitives/LandingButton/LandingButton.spec.d.ts +2 -0
- package/dist/primitives/LandingButton/LandingButton.spec.d.ts.map +1 -0
- package/dist/primitives/LandingButton/LandingButton.spec.js +61 -0
- package/dist/primitives/MenuItem/MenuItem.spec.d.ts +2 -0
- package/dist/primitives/MenuItem/MenuItem.spec.d.ts.map +1 -0
- package/dist/primitives/MenuItem/MenuItem.spec.js +130 -0
- package/dist/primitives/Modal/Modal.spec.js +215 -0
- package/dist/primitives/NavItem/NavItem.spec.d.ts +2 -0
- package/dist/primitives/NavItem/NavItem.spec.d.ts.map +1 -0
- package/dist/primitives/NavItem/NavItem.spec.js +97 -0
- package/dist/primitives/SearchResultItem/SearchResultItem.spec.d.ts +2 -0
- package/dist/primitives/SearchResultItem/SearchResultItem.spec.d.ts.map +1 -0
- package/dist/primitives/SearchResultItem/SearchResultItem.spec.js +78 -0
- package/dist/primitives/SidebarToggle/SidebarToggle.spec.d.ts +2 -0
- package/dist/primitives/SidebarToggle/SidebarToggle.spec.d.ts.map +1 -0
- package/dist/primitives/SidebarToggle/SidebarToggle.spec.js +61 -0
- package/dist/primitives/Spinner/Spinner.spec.js +13 -0
- package/dist/primitives/Toggle.spec.js +75 -0
- package/dist/primitives/ToggleTestWrapper.svelte +30 -0
- package/dist/primitives/ToggleTestWrapper.svelte.d.ts +29 -0
- package/dist/primitives/ToggleTestWrapper.svelte.d.ts.map +1 -0
- package/dist/primitives/Tooltip/Tooltip.spec.d.ts +2 -0
- package/dist/primitives/Tooltip/Tooltip.spec.d.ts.map +1 -0
- package/dist/primitives/Tooltip/Tooltip.spec.js +126 -0
- package/dist/recipes/inputs/Search.spec.js +66 -2
- package/dist/recipes/modals/ConfirmationModal.spec.js +190 -0
- package/dist/schemas/__tests__/auth.test.d.ts +2 -0
- package/dist/schemas/__tests__/auth.test.d.ts.map +1 -0
- package/dist/schemas/__tests__/auth.test.js +210 -0
- package/dist/schemas/__tests__/common.test.d.ts +2 -0
- package/dist/schemas/__tests__/common.test.d.ts.map +1 -0
- package/dist/schemas/__tests__/common.test.js +340 -0
- package/dist/schemas/__tests__/domain.test.d.ts +2 -0
- package/dist/schemas/__tests__/domain.test.d.ts.map +1 -0
- package/dist/schemas/__tests__/domain.test.js +293 -0
- package/dist/schemas/__tests__/order.test.d.ts +2 -0
- package/dist/schemas/__tests__/order.test.d.ts.map +1 -0
- package/dist/schemas/__tests__/order.test.js +349 -0
- package/dist/schemas/__tests__/user.test.d.ts +2 -0
- package/dist/schemas/__tests__/user.test.d.ts.map +1 -0
- package/dist/schemas/__tests__/user.test.js +325 -0
- package/dist/schemas/auth.d.ts +41 -0
- package/dist/schemas/auth.d.ts.map +1 -0
- package/dist/schemas/auth.js +69 -0
- package/dist/schemas/common.d.ts +43 -0
- package/dist/schemas/common.d.ts.map +1 -0
- package/dist/schemas/common.js +157 -0
- package/dist/schemas/event.d.ts +82 -0
- package/dist/schemas/event.d.ts.map +1 -0
- package/dist/schemas/event.js +58 -0
- package/dist/schemas/index.d.ts +10 -0
- package/dist/schemas/index.d.ts.map +1 -0
- package/dist/schemas/index.js +9 -0
- package/dist/schemas/order.d.ts +111 -0
- package/dist/schemas/order.d.ts.map +1 -0
- package/dist/schemas/order.js +73 -0
- package/dist/schemas/performer.d.ts +133 -0
- package/dist/schemas/performer.d.ts.map +1 -0
- package/dist/schemas/performer.js +73 -0
- package/dist/schemas/promo.d.ts +87 -0
- package/dist/schemas/promo.d.ts.map +1 -0
- package/dist/schemas/promo.js +98 -0
- package/dist/schemas/ticket.d.ts +104 -0
- package/dist/schemas/ticket.d.ts.map +1 -0
- package/dist/schemas/ticket.js +82 -0
- package/dist/schemas/user.d.ts +92 -0
- package/dist/schemas/user.d.ts.map +1 -0
- package/dist/schemas/user.js +53 -0
- package/dist/schemas/venue.d.ts +95 -0
- package/dist/schemas/venue.d.ts.map +1 -0
- package/dist/schemas/venue.js +52 -0
- package/dist/stores/auth.svelte.spec.d.ts +2 -0
- package/dist/stores/auth.svelte.spec.d.ts.map +1 -0
- package/dist/stores/auth.svelte.spec.js +112 -0
- package/dist/stores/formDataStore.svelte.spec.d.ts +2 -0
- package/dist/stores/formDataStore.svelte.spec.d.ts.map +1 -0
- package/dist/stores/formDataStore.svelte.spec.js +150 -0
- package/dist/stores/formSave.svelte.spec.d.ts +2 -0
- package/dist/stores/formSave.svelte.spec.d.ts.map +1 -0
- package/dist/stores/formSave.svelte.spec.js +196 -0
- package/dist/stores/navigation.spec.d.ts +2 -0
- package/dist/stores/navigation.spec.d.ts.map +1 -0
- package/dist/stores/navigation.spec.js +53 -0
- package/dist/telemetry.spec.js +5 -0
- package/dist/tokens/__tests__/sizing.test.js +2 -2
- package/dist/tokens/sizing.d.ts +5 -0
- package/dist/tokens/sizing.d.ts.map +1 -1
- package/dist/tokens/sizing.js +6 -0
- package/dist/utils/haptic.spec.d.ts +2 -0
- package/dist/utils/haptic.spec.d.ts.map +1 -0
- package/dist/utils/haptic.spec.js +153 -0
- package/dist/utils/imageOptimizer.spec.d.ts +2 -0
- package/dist/utils/imageOptimizer.spec.d.ts.map +1 -0
- package/dist/utils/imageOptimizer.spec.js +201 -0
- package/dist/utils/logger.spec.d.ts +2 -0
- package/dist/utils/logger.spec.d.ts.map +1 -0
- package/dist/utils/logger.spec.js +95 -0
- package/package.json +1 -2
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { ChevronLeftOutline, ChevronRightOutline, CheckCircleSolid } from '../../primitives/Icons';
|
|
3
3
|
import Spinner from '../../primitives/Spinner/Spinner.svelte';
|
|
4
4
|
import { typography } from '../../tokens/typography';
|
|
5
|
+
import { formatDayOfWeek, formatMonth } from '../../datetime/format';
|
|
5
6
|
|
|
6
7
|
let {
|
|
7
8
|
variant = 'availability',
|
|
@@ -592,13 +593,10 @@
|
|
|
592
593
|
}
|
|
593
594
|
|
|
594
595
|
function getDayAriaLabel(day) {
|
|
595
|
-
const
|
|
596
|
-
const
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
day: 'numeric',
|
|
600
|
-
year: 'numeric'
|
|
601
|
-
});
|
|
596
|
+
const isoStr = new Date(currentYear, currentMonth, day.day).toISOString();
|
|
597
|
+
const dayOfWeek = formatDayOfWeek(isoStr, 'UTC', false);
|
|
598
|
+
const month = formatMonth(isoStr, 'UTC', false);
|
|
599
|
+
const dateStr = `${dayOfWeek}, ${month} ${day.day}, ${currentYear}`;
|
|
602
600
|
|
|
603
601
|
let label = dateStr;
|
|
604
602
|
if (day.isToday) label += ', Today';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MiniMonthCalendar.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/calendar/Calendar/MiniMonthCalendar.svelte.js"],"names":[],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"MiniMonthCalendar.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/calendar/Calendar/MiniMonthCalendar.svelte.js"],"names":[],"mappings":";;;;;AAgtBA;cAlsB+B,MAAM;oBAAkB,GAAG,EAAE;aAAW,GAAG,EAAE;iBAAe,MAAM;iBAAe,OAAO;qBAAmB,OAAO;sBAAoB,OAAO;eAAa,OAAO;yBAAuB,OAAO;4BAA0B,OAAO;kBAAgB,GAAG;gBAAc,GAAG;mBAAiB,GAAG;wBAksBvP;wBAlsB7C;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,aAAa,CAAC,EAAE,GAAG,EAAE,CAAC;IAAC,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,OAAO,CAAC;IAAC,cAAc,CAAC,EAAE,OAAO,CAAC;IAAC,eAAe,CAAC,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAAC,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAAC,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAAC,YAAY,EAAE,GAAG,CAAC;IAAC,UAAU,EAAE,GAAG,CAAC;IAAC,aAAa,EAAE,GAAG,CAAA;CAAE"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import { ChevronLeftOutline, ChevronRightOutline } from '../../primitives/Icons';
|
|
3
3
|
import { typography } from '../../tokens/typography';
|
|
4
|
+
import { formatMonth } from '../../datetime/format';
|
|
4
5
|
|
|
5
6
|
const today = new Date();
|
|
6
7
|
const todayLocalMonth = today.getMonth();
|
|
@@ -63,9 +64,7 @@
|
|
|
63
64
|
|
|
64
65
|
<header class="w-full flex items-center justify-between select-none">
|
|
65
66
|
<h2 class="{typography.h1} text-3xl">
|
|
66
|
-
{new
|
|
67
|
-
month: "long",
|
|
68
|
-
}).format(new Date(currentYear, currentMonth, 1))}
|
|
67
|
+
{formatMonth(new Date(currentYear, currentMonth, 1).toISOString(), 'UTC', false)}
|
|
69
68
|
</h2>
|
|
70
69
|
<div class="flex items-center gap-2">
|
|
71
70
|
<button
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MonthSwitcher.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/calendar/MonthSwitcher/MonthSwitcher.svelte.js"],"names":[],"mappings":";;;;;AA0FA;;;;;;
|
|
1
|
+
{"version":3,"file":"MonthSwitcher.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/calendar/MonthSwitcher/MonthSwitcher.svelte.js"],"names":[],"mappings":";;;;;AA0FA;;;;;;4BA1E+L,OAAO;WA0E1I;wBA1EzC;IAAE,WAAW,CAAC,SAAwB;IAAC,YAAY,CAAC,SAAyB;IAAC,UAAU,CAAC,WAAW;IAAC,UAAU,CAAC,WAAW;IAAC,WAAW,CAAC,WAAW;IAAC,qBAAqB,CAAC,EAAE,OAAO,CAAA;CAAE"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import { typography } from '../../tokens/typography';
|
|
3
|
+
import { formatEventDate as formatDateTz, formatEventTime } from '../../datetime/format';
|
|
3
4
|
|
|
4
5
|
let {
|
|
5
6
|
events = [],
|
|
@@ -14,12 +15,6 @@
|
|
|
14
15
|
|
|
15
16
|
let placeholder = $derived(placeholderImage || DEFAULT_PLACEHOLDER);
|
|
16
17
|
|
|
17
|
-
let options = {
|
|
18
|
-
weekday: "short",
|
|
19
|
-
month: "short",
|
|
20
|
-
day: "numeric",
|
|
21
|
-
};
|
|
22
|
-
|
|
23
18
|
function handleResize() {
|
|
24
19
|
_isSmallScreen = window.innerWidth < 768;
|
|
25
20
|
}
|
|
@@ -62,11 +57,25 @@
|
|
|
62
57
|
return status === 'Sold out' || status === 'Selling fast' || status === 'Almost sold out';
|
|
63
58
|
}
|
|
64
59
|
|
|
65
|
-
function formatEventDate(
|
|
66
|
-
|
|
67
|
-
|
|
60
|
+
function formatEventDate(event) {
|
|
61
|
+
// Prefer timezone-aware formatting via startDateTime + timeZone
|
|
62
|
+
if (event.startDateTime && event.timeZone) {
|
|
63
|
+
return formatDateTz(event.startDateTime, event.timeZone, { includeYear: false });
|
|
64
|
+
}
|
|
65
|
+
// Fallback for legacy event.date (YYYY-MM-DD)
|
|
66
|
+
if (!event.date) return '';
|
|
67
|
+
const [year, month, day] = event.date.split('-').map(Number);
|
|
68
68
|
const date = new Date(year, month - 1, day);
|
|
69
|
-
return date.toLocaleDateString("en-US",
|
|
69
|
+
return date.toLocaleDateString("en-US", { weekday: "short", month: "short", day: "numeric" });
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function formatTime(event) {
|
|
73
|
+
if (event.startDateTime && event.timeZone) {
|
|
74
|
+
return formatEventTime(event.startDateTime, event.timeZone);
|
|
75
|
+
}
|
|
76
|
+
// Fallback for legacy event.timeline
|
|
77
|
+
if (event.timeline) return event.timeline.split("-")[0].trim();
|
|
78
|
+
return '';
|
|
70
79
|
}
|
|
71
80
|
</script>
|
|
72
81
|
|
|
@@ -80,7 +89,7 @@
|
|
|
80
89
|
onkeydown={(e) => handleKeydown(e, event)}
|
|
81
90
|
tabindex="0"
|
|
82
91
|
role="button"
|
|
83
|
-
aria-label={`${event.name}, ${event.status || 'On Sale'}, ${formatEventDate(event
|
|
92
|
+
aria-label={`${event.name}, ${event.status || 'On Sale'}, ${formatEventDate(event)}. Press Enter to view details.`}
|
|
84
93
|
>
|
|
85
94
|
<div
|
|
86
95
|
class="bg-gray-100 dark:bg-gray-700 flex items-center justify-center overflow-hidden {view === 'col'
|
|
@@ -122,10 +131,10 @@
|
|
|
122
131
|
class="{typography.textMuted} {view === 'col' ? 'text-xs' : 'text-xs sm:text-sm'}"
|
|
123
132
|
>
|
|
124
133
|
<span class="font-medium">
|
|
125
|
-
{formatEventDate(event
|
|
126
|
-
{#if event.timeline}
|
|
134
|
+
{formatEventDate(event)}
|
|
135
|
+
{#if event.startDateTime || event.timeline}
|
|
127
136
|
<span class="text-gray-500 dark:text-gray-500">•</span>
|
|
128
|
-
{event
|
|
137
|
+
{formatTime(event)}
|
|
129
138
|
{/if}
|
|
130
139
|
</span>
|
|
131
140
|
</div>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PublicCard.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/calendar/PublicCard/PublicCard.svelte.js"],"names":[],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"PublicCard.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/calendar/PublicCard/PublicCard.svelte.js"],"names":[],"mappings":";;;;;AA8IA;aApI8B,GAAG,EAAE;WAAS,MAAM;uBAAqB,GAAG;kBAAgB,GAAG;WAoIpC;wBApItC;IAAE,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,gBAAgB,CAAC,EAAE,GAAG,CAAC;IAAC,YAAY,EAAE,GAAG,CAAA;CAAE"}
|
|
@@ -281,19 +281,13 @@ describe('ShowCard Component', () => {
|
|
|
281
281
|
});
|
|
282
282
|
|
|
283
283
|
it('handles clipboard error gracefully', async () => {
|
|
284
|
-
const consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
|
|
285
284
|
navigator.clipboard.writeText = vi.fn().mockRejectedValue(new Error('Clipboard failed'));
|
|
286
285
|
|
|
287
286
|
render(ShowCard, { props: { event: mockEvent, showTitle: true } });
|
|
288
287
|
const shareButton = screen.getByLabelText('Share event');
|
|
289
288
|
|
|
289
|
+
// Should not throw — error is silently swallowed
|
|
290
290
|
await fireEvent.click(shareButton);
|
|
291
|
-
|
|
292
|
-
await waitFor(() => {
|
|
293
|
-
expect(consoleErrorSpy).toHaveBeenCalled();
|
|
294
|
-
});
|
|
295
|
-
|
|
296
|
-
consoleErrorSpy.mockRestore();
|
|
297
291
|
});
|
|
298
292
|
|
|
299
293
|
it('handles missing venue name in share text', async () => {
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { ShareOutline, CheckOutline } from '../../primitives/Icons';
|
|
3
3
|
import ShowTimeCard from '../ShowTimeCard/ShowTimeCard.svelte';
|
|
4
4
|
import { typography } from '../../tokens/typography';
|
|
5
|
+
import { formatEventDateTime, formatEventTime } from '../../datetime/format';
|
|
5
6
|
|
|
6
7
|
let {
|
|
7
8
|
event = {},
|
|
@@ -9,6 +10,10 @@
|
|
|
9
10
|
showTitle = true,
|
|
10
11
|
formatDateTime = (dateStr) => {
|
|
11
12
|
if (!dateStr) return '';
|
|
13
|
+
// Use timezone-aware formatting if event has timeZone
|
|
14
|
+
if (event.timeZone) {
|
|
15
|
+
return formatEventDateTime(dateStr, event.timeZone);
|
|
16
|
+
}
|
|
12
17
|
const date = new Date(dateStr);
|
|
13
18
|
if (isNaN(date.getTime())) return dateStr;
|
|
14
19
|
return date.toLocaleDateString('en-US', {
|
|
@@ -22,6 +27,10 @@
|
|
|
22
27
|
},
|
|
23
28
|
formatTimeline = (timeStr) => {
|
|
24
29
|
if (!timeStr) return '';
|
|
30
|
+
// Use timezone-aware formatting if event has timeZone
|
|
31
|
+
if (event.timeZone) {
|
|
32
|
+
return formatEventTime(timeStr, event.timeZone);
|
|
33
|
+
}
|
|
25
34
|
const date = new Date(timeStr);
|
|
26
35
|
if (!isNaN(date.getTime())) {
|
|
27
36
|
return date.toLocaleTimeString('en-US', {
|
|
@@ -69,7 +78,7 @@
|
|
|
69
78
|
shareSuccess = false;
|
|
70
79
|
}, 2000);
|
|
71
80
|
} catch {
|
|
72
|
-
|
|
81
|
+
// Silently fail — both share and clipboard copy failed
|
|
73
82
|
}
|
|
74
83
|
}
|
|
75
84
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ShowCard.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/calendar/ShowCard/ShowCard.svelte.js"],"names":[],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"ShowCard.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/calendar/ShowCard/ShowCard.svelte.js"],"names":[],"mappings":";;;;;AAkKA;YApJ6B,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;gBAAc,GAAG,EAAE;gBAAc,OAAO;;;sBAA0E,GAAG;WAoJ9G;wBApJpC;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAAC,SAAS,CAAC,EAAE,GAAG,EAAE,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,CAAC;IAAC,cAAc,CAAC,WAAW;IAAC,cAAc,CAAC,WAAW;IAAC,gBAAgB,EAAE,GAAG,CAAA;CAAE"}
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import { typography } from '../../tokens/typography';
|
|
3
|
+
import { formatEventTime, formatEventDate } from '../../datetime/format';
|
|
3
4
|
|
|
4
5
|
let {
|
|
5
6
|
day = '',
|
|
6
7
|
date = '',
|
|
7
8
|
time = '',
|
|
9
|
+
timezone = '',
|
|
8
10
|
isSelected = false,
|
|
9
11
|
onselect,
|
|
10
12
|
} = $props();
|
|
@@ -22,6 +24,11 @@
|
|
|
22
24
|
|
|
23
25
|
function formatHour(timeStr) {
|
|
24
26
|
if (!timeStr) return '';
|
|
27
|
+
// If we have an ISO string and timezone, use timezone-aware formatting
|
|
28
|
+
if (timezone && timeStr.includes('T')) {
|
|
29
|
+
return formatEventTime(timeStr, timezone);
|
|
30
|
+
}
|
|
31
|
+
// Fallback for HH:mm time strings
|
|
25
32
|
const d = new Date(`1970-01-01T${timeStr}`);
|
|
26
33
|
if (isNaN(d.getTime())) return timeStr;
|
|
27
34
|
return d.toLocaleTimeString('en-US', {
|
|
@@ -33,6 +40,10 @@
|
|
|
33
40
|
|
|
34
41
|
function formatDate(dateStr) {
|
|
35
42
|
if (!dateStr) return '';
|
|
43
|
+
// If we have timezone, use timezone-aware formatting
|
|
44
|
+
if (timezone) {
|
|
45
|
+
return formatEventDate(dateStr, timezone, { includeYear: false });
|
|
46
|
+
}
|
|
36
47
|
const d = new Date(dateStr);
|
|
37
48
|
if (isNaN(d.getTime())) return dateStr;
|
|
38
49
|
return d.toLocaleDateString('en-US', {
|
|
@@ -7,6 +7,7 @@ declare const ShowTimeCard: import("svelte").Component<{
|
|
|
7
7
|
day?: string;
|
|
8
8
|
date?: string;
|
|
9
9
|
time?: string;
|
|
10
|
+
timezone?: string;
|
|
10
11
|
isSelected?: boolean;
|
|
11
12
|
onselect: any;
|
|
12
13
|
}, {}, "">;
|
|
@@ -14,6 +15,7 @@ type $$ComponentProps = {
|
|
|
14
15
|
day?: string;
|
|
15
16
|
date?: string;
|
|
16
17
|
time?: string;
|
|
18
|
+
timezone?: string;
|
|
17
19
|
isSelected?: boolean;
|
|
18
20
|
onselect: any;
|
|
19
21
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ShowTimeCard.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/calendar/ShowTimeCard/ShowTimeCard.svelte.js"],"names":[],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"ShowTimeCard.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/calendar/ShowTimeCard/ShowTimeCard.svelte.js"],"names":[],"mappings":";;;;;AAyEA;UA/D2B,MAAM;WAAS,MAAM;WAAS,MAAM;eAAa,MAAM;iBAAe,OAAO;cAAY,GAAG;WA+D5D;wBA/DxC;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,GAAG,CAAA;CAAE"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Heading.spec.d.ts","sourceRoot":"","sources":["../../src/lib/components/Heading.spec.js"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { render, screen } from '@testing-library/svelte';
|
|
2
|
+
import { createRawSnippet } from 'svelte';
|
|
3
|
+
import { expect, describe, test } from 'vitest';
|
|
4
|
+
import Heading from './Heading.svelte';
|
|
5
|
+
|
|
6
|
+
function textSnippet(text) {
|
|
7
|
+
return createRawSnippet(() => ({
|
|
8
|
+
render: () => `<span>${text}</span>`
|
|
9
|
+
}));
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
describe('Heading', () => {
|
|
13
|
+
test('renders h2 by default', () => {
|
|
14
|
+
const { container } = render(Heading, { props: { children: textSnippet('Title') } });
|
|
15
|
+
expect(container.querySelector('h2')).toBeInTheDocument();
|
|
16
|
+
expect(container.textContent).toContain('Title');
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
test('renders h1 when level=1', () => {
|
|
20
|
+
const { container } = render(Heading, { props: { level: 1, children: textSnippet('H1') } });
|
|
21
|
+
expect(container.querySelector('h1')).toBeInTheDocument();
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
test('renders h3 when level=3', () => {
|
|
25
|
+
const { container } = render(Heading, { props: { level: 3, children: textSnippet('H3') } });
|
|
26
|
+
expect(container.querySelector('h3')).toBeInTheDocument();
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
test('renders h4 when level=4', () => {
|
|
30
|
+
const { container } = render(Heading, { props: { level: 4, children: textSnippet('H4') } });
|
|
31
|
+
expect(container.querySelector('h4')).toBeInTheDocument();
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
test('renders h5 when level=5', () => {
|
|
35
|
+
const { container } = render(Heading, { props: { level: 5, children: textSnippet('H5') } });
|
|
36
|
+
expect(container.querySelector('h5')).toBeInTheDocument();
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
test('renders h6 when level=6', () => {
|
|
40
|
+
const { container } = render(Heading, { props: { level: 6, children: textSnippet('H6') } });
|
|
41
|
+
expect(container.querySelector('h6')).toBeInTheDocument();
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
test('default size is lg', () => {
|
|
45
|
+
const { container } = render(Heading, { props: { children: textSnippet('Test') } });
|
|
46
|
+
expect(container.querySelector('h2')).toHaveClass('text-lg');
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
test('size xs', () => {
|
|
50
|
+
const { container } = render(Heading, { props: { size: 'xs', children: textSnippet('T') } });
|
|
51
|
+
expect(container.querySelector('h2')).toHaveClass('text-xs');
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
test('size 3xl', () => {
|
|
55
|
+
const { container } = render(Heading, { props: { size: '3xl', children: textSnippet('T') } });
|
|
56
|
+
expect(container.querySelector('h2')).toHaveClass('text-3xl');
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
test('weight bold', () => {
|
|
60
|
+
const { container } = render(Heading, { props: { weight: 'bold', children: textSnippet('T') } });
|
|
61
|
+
expect(container.querySelector('h2')).toHaveClass('font-bold');
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
test('weight semibold', () => {
|
|
65
|
+
const { container } = render(Heading, { props: { weight: 'semibold', children: textSnippet('T') } });
|
|
66
|
+
expect(container.querySelector('h2')).toHaveClass('font-semibold');
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
test('no weight class when not provided', () => {
|
|
70
|
+
const { container } = render(Heading, { props: { children: textSnippet('T') } });
|
|
71
|
+
const h2 = container.querySelector('h2');
|
|
72
|
+
expect(h2.className).not.toContain('font-');
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
test('passes id prop', () => {
|
|
76
|
+
const { container } = render(Heading, { props: { id: 'my-heading', children: textSnippet('T') } });
|
|
77
|
+
expect(container.querySelector('#my-heading')).toBeInTheDocument();
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
test('applies custom className', () => {
|
|
81
|
+
const { container } = render(Heading, { props: { class: 'custom', children: textSnippet('T') } });
|
|
82
|
+
expect(container.querySelector('h2')).toHaveClass('custom');
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
test('has dark mode text class', () => {
|
|
86
|
+
const { container } = render(Heading, { props: { children: textSnippet('T') } });
|
|
87
|
+
expect(container.querySelector('h2').className).toContain('dark:text-white');
|
|
88
|
+
});
|
|
89
|
+
});
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { describe, expect, it } from 'vitest';
|
|
2
2
|
import { render } from '@testing-library/svelte';
|
|
3
|
+
import { createRawSnippet } from 'svelte';
|
|
3
4
|
import AppShell from '../AppShell.svelte';
|
|
4
5
|
describe('AppShell', () => {
|
|
5
6
|
describe('basic rendering', () => {
|
|
@@ -92,4 +93,143 @@ describe('AppShell', () => {
|
|
|
92
93
|
expect(container.querySelector('nav')).toBeFalsy();
|
|
93
94
|
});
|
|
94
95
|
});
|
|
96
|
+
describe('header snippet rendering', () => {
|
|
97
|
+
it('renders header element when header snippet is provided', () => {
|
|
98
|
+
const header = createRawSnippet(() => ({
|
|
99
|
+
render: () => `<div>Header Content</div>`
|
|
100
|
+
}));
|
|
101
|
+
const { container } = render(AppShell, { header });
|
|
102
|
+
const headerEl = container.querySelector('header');
|
|
103
|
+
expect(headerEl).toBeTruthy();
|
|
104
|
+
expect(headerEl?.textContent).toContain('Header Content');
|
|
105
|
+
});
|
|
106
|
+
it('applies fixed positioning classes when fixedHeader=true and header provided', () => {
|
|
107
|
+
const header = createRawSnippet(() => ({
|
|
108
|
+
render: () => `<div>Fixed Header</div>`
|
|
109
|
+
}));
|
|
110
|
+
const { container } = render(AppShell, { header, fixedHeader: true });
|
|
111
|
+
const headerEl = container.querySelector('header');
|
|
112
|
+
expect(headerEl?.classList.contains('fixed')).toBe(true);
|
|
113
|
+
expect(headerEl?.classList.contains('top-0')).toBe(true);
|
|
114
|
+
expect(headerEl?.classList.contains('left-0')).toBe(true);
|
|
115
|
+
});
|
|
116
|
+
it('does not apply fixed positioning when fixedHeader=false and header provided', () => {
|
|
117
|
+
const header = createRawSnippet(() => ({
|
|
118
|
+
render: () => `<div>Non-fixed Header</div>`
|
|
119
|
+
}));
|
|
120
|
+
const { container } = render(AppShell, { header, fixedHeader: false });
|
|
121
|
+
const headerEl = container.querySelector('header');
|
|
122
|
+
expect(headerEl?.classList.contains('fixed')).toBe(false);
|
|
123
|
+
expect(headerEl?.classList.contains('top-0')).toBe(false);
|
|
124
|
+
expect(headerEl?.classList.contains('left-0')).toBe(false);
|
|
125
|
+
});
|
|
126
|
+
it('header has z-30 and w-full classes', () => {
|
|
127
|
+
const header = createRawSnippet(() => ({
|
|
128
|
+
render: () => `<div>Header</div>`
|
|
129
|
+
}));
|
|
130
|
+
const { container } = render(AppShell, { header });
|
|
131
|
+
const headerEl = container.querySelector('header');
|
|
132
|
+
expect(headerEl?.classList.contains('w-full')).toBe(true);
|
|
133
|
+
expect(headerEl?.classList.contains('z-30')).toBe(true);
|
|
134
|
+
});
|
|
135
|
+
});
|
|
136
|
+
describe('sidebar snippet rendering', () => {
|
|
137
|
+
it('renders aside element when sidebar snippet is provided', () => {
|
|
138
|
+
const sidebar = createRawSnippet(() => ({
|
|
139
|
+
render: () => `<div>Sidebar Content</div>`
|
|
140
|
+
}));
|
|
141
|
+
const { container } = render(AppShell, { sidebar });
|
|
142
|
+
const aside = container.querySelector('aside');
|
|
143
|
+
expect(aside).toBeTruthy();
|
|
144
|
+
expect(aside?.textContent).toContain('Sidebar Content');
|
|
145
|
+
});
|
|
146
|
+
it('applies w-64 when sidebar provided and sidebarCollapsed=false', () => {
|
|
147
|
+
const sidebar = createRawSnippet(() => ({
|
|
148
|
+
render: () => `<div>Sidebar</div>`
|
|
149
|
+
}));
|
|
150
|
+
const { container } = render(AppShell, { sidebar, sidebarCollapsed: false });
|
|
151
|
+
const aside = container.querySelector('aside');
|
|
152
|
+
expect(aside?.classList.contains('w-64')).toBe(true);
|
|
153
|
+
expect(aside?.classList.contains('w-20')).toBe(false);
|
|
154
|
+
});
|
|
155
|
+
it('applies w-20 when sidebar provided and sidebarCollapsed=true', () => {
|
|
156
|
+
const sidebar = createRawSnippet(() => ({
|
|
157
|
+
render: () => `<div>Sidebar</div>`
|
|
158
|
+
}));
|
|
159
|
+
const { container } = render(AppShell, { sidebar, sidebarCollapsed: true });
|
|
160
|
+
const aside = container.querySelector('aside');
|
|
161
|
+
expect(aside?.classList.contains('w-20')).toBe(true);
|
|
162
|
+
expect(aside?.classList.contains('w-64')).toBe(false);
|
|
163
|
+
});
|
|
164
|
+
it('applies md:ml-64 to main when sidebar provided and not collapsed', () => {
|
|
165
|
+
const sidebar = createRawSnippet(() => ({
|
|
166
|
+
render: () => `<div>Sidebar</div>`
|
|
167
|
+
}));
|
|
168
|
+
const { container } = render(AppShell, { sidebar, sidebarCollapsed: false });
|
|
169
|
+
const main = container.querySelector('main');
|
|
170
|
+
expect(main?.classList.contains('md:ml-64')).toBe(true);
|
|
171
|
+
});
|
|
172
|
+
it('applies md:ml-20 to main when sidebar provided and collapsed', () => {
|
|
173
|
+
const sidebar = createRawSnippet(() => ({
|
|
174
|
+
render: () => `<div>Sidebar</div>`
|
|
175
|
+
}));
|
|
176
|
+
const { container } = render(AppShell, { sidebar, sidebarCollapsed: true });
|
|
177
|
+
const main = container.querySelector('main');
|
|
178
|
+
expect(main?.classList.contains('md:ml-20')).toBe(true);
|
|
179
|
+
});
|
|
180
|
+
});
|
|
181
|
+
describe('bottomNav snippet rendering', () => {
|
|
182
|
+
it('renders nav element when bottomNav snippet and showBottomNav=true', () => {
|
|
183
|
+
const bottomNav = createRawSnippet(() => ({
|
|
184
|
+
render: () => `<div>Bottom Nav</div>`
|
|
185
|
+
}));
|
|
186
|
+
const { container } = render(AppShell, { bottomNav, showBottomNav: true });
|
|
187
|
+
const nav = container.querySelector('nav');
|
|
188
|
+
expect(nav).toBeTruthy();
|
|
189
|
+
expect(nav?.textContent).toContain('Bottom Nav');
|
|
190
|
+
});
|
|
191
|
+
it('does not render nav when bottomNav provided but showBottomNav=false', () => {
|
|
192
|
+
const bottomNav = createRawSnippet(() => ({
|
|
193
|
+
render: () => `<div>Bottom Nav</div>`
|
|
194
|
+
}));
|
|
195
|
+
const { container } = render(AppShell, { bottomNav, showBottomNav: false });
|
|
196
|
+
expect(container.querySelector('nav')).toBeFalsy();
|
|
197
|
+
});
|
|
198
|
+
it('applies pb-16 to main when bottomNav and showBottomNav are set', () => {
|
|
199
|
+
const bottomNav = createRawSnippet(() => ({
|
|
200
|
+
render: () => `<div>Bottom Nav</div>`
|
|
201
|
+
}));
|
|
202
|
+
const { container } = render(AppShell, { bottomNav, showBottomNav: true });
|
|
203
|
+
const main = container.querySelector('main');
|
|
204
|
+
expect(main?.classList.contains('pb-16')).toBe(true);
|
|
205
|
+
});
|
|
206
|
+
it('nav has fixed bottom positioning and z-30', () => {
|
|
207
|
+
const bottomNav = createRawSnippet(() => ({
|
|
208
|
+
render: () => `<div>Bottom Nav</div>`
|
|
209
|
+
}));
|
|
210
|
+
const { container } = render(AppShell, { bottomNav, showBottomNav: true });
|
|
211
|
+
const nav = container.querySelector('nav');
|
|
212
|
+
expect(nav?.classList.contains('fixed')).toBe(true);
|
|
213
|
+
expect(nav?.classList.contains('bottom-0')).toBe(true);
|
|
214
|
+
expect(nav?.classList.contains('z-30')).toBe(true);
|
|
215
|
+
});
|
|
216
|
+
});
|
|
217
|
+
describe('children snippet rendering', () => {
|
|
218
|
+
it('renders children content in main area', () => {
|
|
219
|
+
const children = createRawSnippet(() => ({
|
|
220
|
+
render: () => `<div>Main Content</div>`
|
|
221
|
+
}));
|
|
222
|
+
const { container } = render(AppShell, { children });
|
|
223
|
+
const main = container.querySelector('main');
|
|
224
|
+
expect(main?.textContent).toContain('Main Content');
|
|
225
|
+
});
|
|
226
|
+
it('does not render children placeholder when no children provided', () => {
|
|
227
|
+
const { container } = render(AppShell);
|
|
228
|
+
const main = container.querySelector('main');
|
|
229
|
+
const innerDiv = main?.querySelector('div');
|
|
230
|
+
expect(innerDiv).toBeTruthy();
|
|
231
|
+
// Inner div should be empty when no children
|
|
232
|
+
expect(innerDiv?.children.length).toBe(0);
|
|
233
|
+
});
|
|
234
|
+
});
|
|
95
235
|
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Text.spec.d.ts","sourceRoot":"","sources":["../../src/lib/components/Text.spec.js"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { render } from '@testing-library/svelte';
|
|
2
|
+
import { createRawSnippet } from 'svelte';
|
|
3
|
+
import { expect, describe, test } from 'vitest';
|
|
4
|
+
import Text from './Text.svelte';
|
|
5
|
+
|
|
6
|
+
function textSnippet(text) {
|
|
7
|
+
return createRawSnippet(() => ({
|
|
8
|
+
render: () => `<span>${text}</span>`
|
|
9
|
+
}));
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
describe('Text', () => {
|
|
13
|
+
test('renders a span element', () => {
|
|
14
|
+
const { container } = render(Text, { props: { children: textSnippet('Hello') } });
|
|
15
|
+
expect(container.querySelector('span')).toBeInTheDocument();
|
|
16
|
+
expect(container.textContent).toContain('Hello');
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
test('default size is md (text-base)', () => {
|
|
20
|
+
const { container } = render(Text, { props: { children: textSnippet('T') } });
|
|
21
|
+
expect(container.querySelector('span')).toHaveClass('text-base');
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
test('size xs', () => {
|
|
25
|
+
const { container } = render(Text, { props: { size: 'xs', children: textSnippet('T') } });
|
|
26
|
+
expect(container.querySelector('span')).toHaveClass('text-xs');
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
test('size lg', () => {
|
|
30
|
+
const { container } = render(Text, { props: { size: 'lg', children: textSnippet('T') } });
|
|
31
|
+
expect(container.querySelector('span')).toHaveClass('text-lg');
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
test('size 2xl', () => {
|
|
35
|
+
const { container } = render(Text, { props: { size: '2xl', children: textSnippet('T') } });
|
|
36
|
+
expect(container.querySelector('span')).toHaveClass('text-2xl');
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
test('default color is default (gray-900)', () => {
|
|
40
|
+
const { container } = render(Text, { props: { children: textSnippet('T') } });
|
|
41
|
+
expect(container.querySelector('span').className).toContain('text-gray-900');
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
test('color muted', () => {
|
|
45
|
+
const { container } = render(Text, { props: { color: 'muted', children: textSnippet('T') } });
|
|
46
|
+
expect(container.querySelector('span').className).toContain('text-gray-500');
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
test('color success', () => {
|
|
50
|
+
const { container } = render(Text, { props: { color: 'success', children: textSnippet('T') } });
|
|
51
|
+
expect(container.querySelector('span').className).toContain('text-green-600');
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
test('color error', () => {
|
|
55
|
+
const { container } = render(Text, { props: { color: 'error', children: textSnippet('T') } });
|
|
56
|
+
expect(container.querySelector('span').className).toContain('text-red-600');
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
test('leading tight', () => {
|
|
60
|
+
const { container } = render(Text, { props: { leading: 'tight', children: textSnippet('T') } });
|
|
61
|
+
expect(container.querySelector('span')).toHaveClass('leading-tight');
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
test('leading relaxed', () => {
|
|
65
|
+
const { container } = render(Text, { props: { leading: 'relaxed', children: textSnippet('T') } });
|
|
66
|
+
expect(container.querySelector('span')).toHaveClass('leading-relaxed');
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
test('no leading class when not provided', () => {
|
|
70
|
+
const { container } = render(Text, { props: { children: textSnippet('T') } });
|
|
71
|
+
const cls = container.querySelector('span').className;
|
|
72
|
+
expect(cls).not.toContain('leading-');
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
test('applies custom className', () => {
|
|
76
|
+
const { container } = render(Text, { props: { class: 'custom-text', children: textSnippet('T') } });
|
|
77
|
+
expect(container.querySelector('span')).toHaveClass('custom-text');
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
test('invalid size falls back to text-base', () => {
|
|
81
|
+
const { container } = render(Text, { props: { size: 'invalid', children: textSnippet('T') } });
|
|
82
|
+
expect(container.querySelector('span')).toHaveClass('text-base');
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
test('invalid color falls back gracefully', () => {
|
|
86
|
+
const { container } = render(Text, { props: { color: 'invalid', children: textSnippet('T') } });
|
|
87
|
+
expect(container.querySelector('span')).toBeInTheDocument();
|
|
88
|
+
});
|
|
89
|
+
});
|