@joewinke/jatui 0.1.25 → 0.1.26
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/actions/collapse.d.ts +80 -0
- package/dist/actions/collapse.js +134 -0
- package/dist/actions/railNav.d.ts +167 -0
- package/dist/actions/railNav.js +351 -0
- package/dist/components/AnnotationLayer.svelte +108 -0
- package/dist/components/AnnotationLayer.svelte.d.ts +12 -0
- package/dist/components/AnnotationPanel.svelte +319 -0
- package/dist/components/AnnotationPanel.svelte.d.ts +13 -0
- package/dist/components/AudioWaveform.svelte +701 -0
- package/dist/components/AudioWaveform.svelte.d.ts +19 -0
- package/dist/components/AvailabilityModal.svelte +177 -0
- package/dist/components/AvailabilityModal.svelte.d.ts +14 -0
- package/dist/components/AvatarUpload.svelte +234 -0
- package/dist/components/AvatarUpload.svelte.d.ts +23 -0
- package/dist/components/Badge.svelte +38 -0
- package/dist/components/Badge.svelte.d.ts +14 -0
- package/dist/components/BookingForm.svelte +278 -0
- package/dist/components/BookingForm.svelte.d.ts +37 -0
- package/dist/components/BurndownChart.svelte +778 -0
- package/dist/components/BurndownChart.svelte.d.ts +17 -0
- package/dist/components/Button.svelte +81 -0
- package/dist/components/Button.svelte.d.ts +21 -0
- package/dist/components/CalendarPicker.svelte +284 -0
- package/dist/components/CalendarPicker.svelte.d.ts +22 -0
- package/dist/components/Card.svelte +67 -0
- package/dist/components/Card.svelte.d.ts +17 -0
- package/dist/components/CharacterCounter.svelte +82 -0
- package/dist/components/CharacterCounter.svelte.d.ts +10 -0
- package/dist/components/ChipInput.svelte +609 -0
- package/dist/components/ChipInput.svelte.d.ts +55 -0
- package/dist/components/Collapse.svelte +91 -0
- package/dist/components/Collapse.svelte.d.ts +18 -0
- package/dist/components/ColorSelector.svelte +167 -0
- package/dist/components/ColorSelector.svelte.d.ts +9 -0
- package/dist/components/CommentThread.svelte +773 -0
- package/dist/components/CommentThread.svelte.d.ts +32 -0
- package/dist/components/ConfirmDialog.svelte +348 -0
- package/dist/components/ConfirmDialog.svelte.d.ts +3 -0
- package/dist/components/ConfirmModal.svelte +142 -0
- package/dist/components/ConfirmModal.svelte.d.ts +15 -0
- package/dist/components/ContextMenu.svelte +188 -0
- package/dist/components/ContextMenu.svelte.d.ts +31 -0
- package/dist/components/CountdownTimer.svelte +94 -0
- package/dist/components/CountdownTimer.svelte.d.ts +10 -0
- package/dist/components/DateRangePicker.svelte +194 -0
- package/dist/components/DateRangePicker.svelte.d.ts +10 -0
- package/dist/components/Drawer.svelte +143 -0
- package/dist/components/Drawer.svelte.d.ts +33 -0
- package/dist/components/EmojiPicker.svelte +159 -0
- package/dist/components/EmojiPicker.svelte.d.ts +8 -0
- package/dist/components/EntityPreviewCard.svelte +104 -0
- package/dist/components/EntityPreviewCard.svelte.d.ts +9 -0
- package/dist/components/FileDropzone.svelte +493 -0
- package/dist/components/FileDropzone.svelte.d.ts +40 -0
- package/dist/components/FilePicker.svelte +488 -0
- package/dist/components/FilePicker.svelte.d.ts +20 -0
- package/dist/components/FileThumbnail.svelte +80 -0
- package/dist/components/FileThumbnail.svelte.d.ts +12 -0
- package/dist/components/FilterDropdown.svelte +203 -0
- package/dist/components/FilterDropdown.svelte.d.ts +48 -0
- package/dist/components/FloatingActionBar.svelte +354 -0
- package/dist/components/FloatingActionBar.svelte.d.ts +51 -0
- package/dist/components/GPSTracker.svelte +202 -0
- package/dist/components/GPSTracker.svelte.d.ts +34 -0
- package/dist/components/HunkDiffView.svelte +348 -0
- package/dist/components/HunkDiffView.svelte.d.ts +9 -0
- package/dist/components/ImageLightbox.svelte +274 -0
- package/dist/components/ImageLightbox.svelte.d.ts +25 -0
- package/dist/components/ImageUpload.svelte +147 -0
- package/dist/components/ImageUpload.svelte.d.ts +10 -0
- package/dist/components/InlineEdit.svelte +291 -0
- package/dist/components/InlineEdit.svelte.d.ts +45 -0
- package/dist/components/InputDialog.svelte +327 -0
- package/dist/components/InputDialog.svelte.d.ts +3 -0
- package/dist/components/KeyboardShortcutsOverlay.svelte +296 -0
- package/dist/components/KeyboardShortcutsOverlay.svelte.d.ts +42 -0
- package/dist/components/LazyImage.svelte +123 -0
- package/dist/components/LazyImage.svelte.d.ts +14 -0
- package/dist/components/LinkShortener.svelte +274 -0
- package/dist/components/LinkShortener.svelte.d.ts +27 -0
- package/dist/components/LoadingSpinner.svelte +106 -0
- package/dist/components/LoadingSpinner.svelte.d.ts +21 -0
- package/dist/components/LocationMap.svelte +186 -0
- package/dist/components/LocationMap.svelte.d.ts +11 -0
- package/dist/components/MapView.svelte +341 -0
- package/dist/components/MapView.svelte.d.ts +20 -0
- package/dist/components/MarkupEditor.svelte +485 -0
- package/dist/components/MarkupEditor.svelte.d.ts +10 -0
- package/dist/components/MarkupOverlay.svelte +55 -0
- package/dist/components/MarkupOverlay.svelte.d.ts +8 -0
- package/dist/components/MediaWorkbench.svelte +871 -0
- package/dist/components/MediaWorkbench.svelte.d.ts +9 -0
- package/dist/components/MilestoneCard.svelte +98 -0
- package/dist/components/MilestoneCard.svelte.d.ts +16 -0
- package/dist/components/MilestoneTimeline.svelte +91 -0
- package/dist/components/MilestoneTimeline.svelte.d.ts +15 -0
- package/dist/components/Modal.svelte +244 -0
- package/dist/components/Modal.svelte.d.ts +35 -0
- package/dist/components/PDFViewer.svelte +105 -0
- package/dist/components/PDFViewer.svelte.d.ts +9 -0
- package/dist/components/PdfThumbnail.svelte +63 -0
- package/dist/components/PdfThumbnail.svelte.d.ts +9 -0
- package/dist/components/PhoneInput.svelte +212 -0
- package/dist/components/PhoneInput.svelte.d.ts +25 -0
- package/dist/components/ResizableDivider.svelte +307 -0
- package/dist/components/ResizableDivider.svelte.d.ts +26 -0
- package/dist/components/ResizablePanel.svelte +305 -0
- package/dist/components/ResizablePanel.svelte.d.ts +18 -0
- package/dist/components/SearchDropdown.svelte +421 -0
- package/dist/components/SearchDropdown.svelte.d.ts +24 -0
- package/dist/components/SelectInput.svelte +237 -0
- package/dist/components/SelectInput.svelte.d.ts +26 -0
- package/dist/components/SidebarUserFooter.svelte +34 -0
- package/dist/components/SidebarUserFooter.svelte.d.ts +16 -0
- package/dist/components/SignaturePad.svelte +175 -0
- package/dist/components/SignaturePad.svelte.d.ts +17 -0
- package/dist/components/SmartImageEditor.svelte +720 -0
- package/dist/components/SmartImageEditor.svelte.d.ts +24 -0
- package/dist/components/SortDropdown.svelte +156 -0
- package/dist/components/SortDropdown.svelte.d.ts +40 -0
- package/dist/components/Sparkline.svelte +116 -0
- package/dist/components/Sparkline.svelte.d.ts +12 -0
- package/dist/components/SpeechForm.svelte +114 -0
- package/dist/components/SpeechForm.svelte.d.ts +17 -0
- package/dist/components/StatusBadge.svelte +157 -0
- package/dist/components/StatusBadge.svelte.d.ts +24 -0
- package/dist/components/TaskTypeIcon.svelte +54 -0
- package/dist/components/TaskTypeIcon.svelte.d.ts +17 -0
- package/dist/components/TextArea.svelte +162 -0
- package/dist/components/TextArea.svelte.d.ts +30 -0
- package/dist/components/TextInput.svelte +131 -0
- package/dist/components/TextInput.svelte.d.ts +29 -0
- package/dist/components/ThemeSelector.svelte +206 -0
- package/dist/components/ThemeSelector.svelte.d.ts +14 -0
- package/dist/components/TimeSlotPicker.svelte +162 -0
- package/dist/components/TimeSlotPicker.svelte.d.ts +18 -0
- package/dist/components/UserAvatar.svelte +72 -0
- package/dist/components/UserAvatar.svelte.d.ts +11 -0
- package/dist/components/VariablePicker.svelte +170 -0
- package/dist/components/VariablePicker.svelte.d.ts +40 -0
- package/dist/components/VoicePlayer.svelte +422 -0
- package/dist/components/VoicePlayer.svelte.d.ts +18 -0
- package/dist/components/linked-columns/LinkedColumns.svelte +526 -0
- package/dist/components/linked-columns/LinkedColumns.svelte.d.ts +130 -0
- package/dist/components/markup.d.ts +47 -0
- package/dist/components/markup.js +201 -0
- package/dist/components/messaging/Avatar.svelte +81 -0
- package/dist/components/messaging/Avatar.svelte.d.ts +11 -0
- package/dist/components/messaging/ChannelInfoModal.svelte +163 -0
- package/dist/components/messaging/ChannelInfoModal.svelte.d.ts +18 -0
- package/dist/components/messaging/ChannelList.svelte +107 -0
- package/dist/components/messaging/ChannelList.svelte.d.ts +11 -0
- package/dist/components/messaging/ChannelMemberAvatarStack.svelte +69 -0
- package/dist/components/messaging/ChannelMemberAvatarStack.svelte.d.ts +11 -0
- package/dist/components/messaging/ChannelMembersModal.svelte +182 -0
- package/dist/components/messaging/ChannelMembersModal.svelte.d.ts +16 -0
- package/dist/components/messaging/CreateChannelModal.svelte +190 -0
- package/dist/components/messaging/CreateChannelModal.svelte.d.ts +14 -0
- package/dist/components/messaging/DirectMessageList.svelte +145 -0
- package/dist/components/messaging/DirectMessageList.svelte.d.ts +12 -0
- package/dist/components/messaging/EmojiSelector.svelte +261 -0
- package/dist/components/messaging/EmojiSelector.svelte.d.ts +19 -0
- package/dist/components/messaging/MentionAutocomplete.svelte +193 -0
- package/dist/components/messaging/MentionAutocomplete.svelte.d.ts +17 -0
- package/dist/components/messaging/MessageAttachment.svelte +273 -0
- package/dist/components/messaging/MessageAttachment.svelte.d.ts +13 -0
- package/dist/components/messaging/MessageAttachmentUpload.svelte +243 -0
- package/dist/components/messaging/MessageAttachmentUpload.svelte.d.ts +19 -0
- package/dist/components/messaging/MessageInput.svelte +452 -0
- package/dist/components/messaging/MessageInput.svelte.d.ts +28 -0
- package/dist/components/messaging/MessageItem.svelte +341 -0
- package/dist/components/messaging/MessageItem.svelte.d.ts +41 -0
- package/dist/components/messaging/MessageThread.svelte +306 -0
- package/dist/components/messaging/MessageThread.svelte.d.ts +30 -0
- package/dist/components/messaging/NotificationSettingsModal.svelte +234 -0
- package/dist/components/messaging/NotificationSettingsModal.svelte.d.ts +13 -0
- package/dist/components/messaging/QuotedMessageDisplay.svelte +123 -0
- package/dist/components/messaging/QuotedMessageDisplay.svelte.d.ts +10 -0
- package/dist/components/messaging/StartDMModal.svelte +100 -0
- package/dist/components/messaging/StartDMModal.svelte.d.ts +14 -0
- package/dist/components/messaging/ThreadPanel.svelte +153 -0
- package/dist/components/messaging/ThreadPanel.svelte.d.ts +16 -0
- package/dist/components/pipeline/DESIGN.md +361 -0
- package/dist/components/pipeline/Pipeline.svelte +391 -0
- package/dist/components/pipeline/Pipeline.svelte.d.ts +28 -0
- package/dist/components/pipeline/PipelineCard.svelte +94 -0
- package/dist/components/pipeline/PipelineCard.svelte.d.ts +13 -0
- package/dist/components/pipeline/PipelineColumn.svelte +163 -0
- package/dist/components/pipeline/PipelineColumn.svelte.d.ts +30 -0
- package/dist/components/replay/ChapterTimeline.svelte +326 -0
- package/dist/components/replay/ChapterTimeline.svelte.d.ts +39 -0
- package/dist/components/session-nav/transcriptModel.d.ts +132 -0
- package/dist/components/session-nav/transcriptModel.js +285 -0
- package/dist/data/emojis.d.ts +18 -0
- package/dist/data/emojis.js +1196 -0
- package/dist/index.d.ts +142 -0
- package/dist/index.js +142 -0
- package/dist/stores/confirmDialog.svelte.d.ts +21 -0
- package/dist/stores/confirmDialog.svelte.js +31 -0
- package/dist/stores/inputDialog.svelte.d.ts +24 -0
- package/dist/stores/inputDialog.svelte.js +32 -0
- package/dist/styles/rail.css +63 -0
- package/dist/types/annotation.d.ts +32 -0
- package/dist/types/annotation.js +3 -0
- package/dist/types/booking.d.ts +115 -0
- package/dist/types/booking.js +24 -0
- package/dist/types/comments.d.ts +65 -0
- package/dist/types/comments.js +22 -0
- package/dist/types/entityPreview.d.ts +42 -0
- package/dist/types/entityPreview.js +10 -0
- package/dist/types/filePicker.d.ts +15 -0
- package/dist/types/filePicker.js +1 -0
- package/dist/types/googleMaps.d.ts +51 -0
- package/dist/types/maps.d.ts +43 -0
- package/dist/types/maps.js +4 -0
- package/dist/types/messaging.d.ts +282 -0
- package/dist/types/messaging.js +100 -0
- package/dist/types/milestone.d.ts +20 -0
- package/dist/types/milestone.js +7 -0
- package/dist/types/pipeline.d.ts +115 -0
- package/dist/types/pipeline.js +15 -0
- package/dist/types/smartImageEditor.d.ts +42 -0
- package/dist/types/smartImageEditor.js +1 -0
- package/dist/types/templateVars.d.ts +34 -0
- package/dist/types/templateVars.js +12 -0
- package/dist/utils/currency.d.ts +8 -0
- package/dist/utils/currency.js +17 -0
- package/dist/utils/daisyuiColors.d.ts +37 -0
- package/dist/utils/daisyuiColors.js +152 -0
- package/dist/utils/dateFormatters.d.ts +69 -0
- package/dist/utils/dateFormatters.js +199 -0
- package/dist/utils/googleMapsLoader.d.ts +19 -0
- package/dist/utils/googleMapsLoader.js +121 -0
- package/dist/utils/mentionParser.d.ts +67 -0
- package/dist/utils/mentionParser.js +132 -0
- package/dist/utils/phone.d.ts +13 -0
- package/dist/utils/phone.js +67 -0
- package/dist/utils/phoneFormat.d.ts +26 -0
- package/dist/utils/phoneFormat.js +69 -0
- package/dist/utils/taskUtils.d.ts +37 -0
- package/dist/utils/taskUtils.js +71 -0
- package/package.json +3 -2
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Date formatting utilities for consistent date/time display.
|
|
3
|
+
*
|
|
4
|
+
* UTC/ISO Timestamp Handling:
|
|
5
|
+
* Database timestamps are often stored without timezone info (e.g., "2024-11-21 15:30:00").
|
|
6
|
+
* These utilities normalize timestamps to ensure correct UTC parsing.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Normalize a timestamp string to proper ISO 8601 format.
|
|
10
|
+
* Handles database timestamps that may lack 'T' separator or 'Z' suffix.
|
|
11
|
+
*/
|
|
12
|
+
export function normalizeTimestamp(timestamp) {
|
|
13
|
+
if (!timestamp)
|
|
14
|
+
return timestamp;
|
|
15
|
+
if (timestamp.includes('T')) {
|
|
16
|
+
if (timestamp.endsWith('Z'))
|
|
17
|
+
return timestamp;
|
|
18
|
+
if (/[+-]\d{2}:\d{2}$/.test(timestamp))
|
|
19
|
+
return timestamp;
|
|
20
|
+
return timestamp + 'Z';
|
|
21
|
+
}
|
|
22
|
+
return timestamp.replace(' ', 'T') + 'Z';
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Parse a potentially non-standard timestamp into a Date object.
|
|
26
|
+
* Accepts a Date (returned by postgres.js), ISO string, or null/undefined.
|
|
27
|
+
*/
|
|
28
|
+
export function parseTimestamp(timestamp) {
|
|
29
|
+
if (!timestamp)
|
|
30
|
+
return null;
|
|
31
|
+
if (timestamp instanceof Date)
|
|
32
|
+
return isNaN(timestamp.getTime()) ? null : timestamp;
|
|
33
|
+
var normalized = normalizeTimestamp(timestamp);
|
|
34
|
+
var date = new Date(normalized);
|
|
35
|
+
return isNaN(date.getTime()) ? null : date;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Format relative time (e.g., "2d", "3mo", "1y").
|
|
39
|
+
* Compact format suitable for tables and compact UIs.
|
|
40
|
+
*/
|
|
41
|
+
export function formatRelativeTime(dateStr) {
|
|
42
|
+
if (!dateStr)
|
|
43
|
+
return '-';
|
|
44
|
+
var date = parseTimestamp(dateStr);
|
|
45
|
+
if (!date)
|
|
46
|
+
return '-';
|
|
47
|
+
var now = new Date();
|
|
48
|
+
var diffMs = now.getTime() - date.getTime();
|
|
49
|
+
var diffMins = Math.floor(diffMs / (1000 * 60));
|
|
50
|
+
var diffHours = Math.floor(diffMs / (1000 * 60 * 60));
|
|
51
|
+
var diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24));
|
|
52
|
+
var diffWeeks = Math.floor(diffDays / 7);
|
|
53
|
+
var diffMonths = Math.floor(diffDays / 30);
|
|
54
|
+
var diffYears = Math.floor(diffDays / 365);
|
|
55
|
+
if (diffMins < 1)
|
|
56
|
+
return 'now';
|
|
57
|
+
if (diffMins < 60)
|
|
58
|
+
return "".concat(diffMins, "m");
|
|
59
|
+
if (diffHours < 24)
|
|
60
|
+
return "".concat(diffHours, "h");
|
|
61
|
+
if (diffDays < 7)
|
|
62
|
+
return "".concat(diffDays, "d");
|
|
63
|
+
if (diffWeeks < 4)
|
|
64
|
+
return "".concat(diffWeeks, "w");
|
|
65
|
+
if (diffMonths < 12)
|
|
66
|
+
return "".concat(diffMonths, "mo");
|
|
67
|
+
return "".concat(diffYears, "y");
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Format full date and time for tooltips and detailed views.
|
|
71
|
+
*/
|
|
72
|
+
export function formatFullDate(dateStr) {
|
|
73
|
+
if (!dateStr)
|
|
74
|
+
return '';
|
|
75
|
+
var date = parseTimestamp(dateStr);
|
|
76
|
+
if (!date)
|
|
77
|
+
return '';
|
|
78
|
+
return date.toLocaleString('en-US', {
|
|
79
|
+
month: 'short',
|
|
80
|
+
day: 'numeric',
|
|
81
|
+
year: 'numeric',
|
|
82
|
+
hour: '2-digit',
|
|
83
|
+
minute: '2-digit'
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Format short date for compact displays (e.g., date range picker).
|
|
88
|
+
*/
|
|
89
|
+
export function formatShortDate(dateStr) {
|
|
90
|
+
if (!dateStr)
|
|
91
|
+
return '';
|
|
92
|
+
var date = parseTimestamp(dateStr);
|
|
93
|
+
if (!date)
|
|
94
|
+
return '';
|
|
95
|
+
return date.toLocaleDateString('en-US', { month: 'short', day: 'numeric' });
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Format last activity time for agent cards.
|
|
99
|
+
* Shows "Just now", "Xm ago", "Xh ago", or "Xd ago".
|
|
100
|
+
*/
|
|
101
|
+
export function formatLastActivity(timestamp) {
|
|
102
|
+
if (!timestamp)
|
|
103
|
+
return 'Never';
|
|
104
|
+
var date = parseTimestamp(timestamp);
|
|
105
|
+
if (!date)
|
|
106
|
+
return 'Never';
|
|
107
|
+
var now = new Date();
|
|
108
|
+
var diffMs = now.getTime() - date.getTime();
|
|
109
|
+
var diffMins = Math.floor(diffMs / 60000);
|
|
110
|
+
var diffHours = Math.floor(diffMs / 3600000);
|
|
111
|
+
var diffDays = Math.floor(diffMs / 86400000);
|
|
112
|
+
if (diffMins < 1)
|
|
113
|
+
return 'Just now';
|
|
114
|
+
if (diffMins < 60)
|
|
115
|
+
return "".concat(diffMins, "m ago");
|
|
116
|
+
if (diffHours < 24)
|
|
117
|
+
return "".concat(diffHours, "h ago");
|
|
118
|
+
return "".concat(diffDays, "d ago");
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Format date for display (simple locale string).
|
|
122
|
+
*/
|
|
123
|
+
export function formatDate(dateString) {
|
|
124
|
+
if (!dateString)
|
|
125
|
+
return 'N/A';
|
|
126
|
+
var date = parseTimestamp(dateString);
|
|
127
|
+
if (!date)
|
|
128
|
+
return 'N/A';
|
|
129
|
+
return date.toLocaleString();
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Get milliseconds since timestamp (for calculations).
|
|
133
|
+
*/
|
|
134
|
+
export function getTimeSinceMs(timestamp) {
|
|
135
|
+
if (!timestamp)
|
|
136
|
+
return Infinity;
|
|
137
|
+
var date = parseTimestamp(timestamp);
|
|
138
|
+
if (!date)
|
|
139
|
+
return Infinity;
|
|
140
|
+
return Date.now() - date.getTime();
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Get minutes since timestamp.
|
|
144
|
+
*/
|
|
145
|
+
export function getTimeSinceMinutes(timestamp) {
|
|
146
|
+
return getTimeSinceMs(timestamp) / 60000;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Check if timestamp is within a given number of minutes.
|
|
150
|
+
*/
|
|
151
|
+
export function isWithinMinutes(timestamp, minutes) {
|
|
152
|
+
return getTimeSinceMinutes(timestamp) < minutes;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Format date + time for detail views (e.g. "Jan 5, 2:30 PM").
|
|
156
|
+
* No year — use formatFullDate when year is needed.
|
|
157
|
+
*/
|
|
158
|
+
export function formatDateTime(dateStr) {
|
|
159
|
+
if (!dateStr)
|
|
160
|
+
return '';
|
|
161
|
+
var date = parseTimestamp(dateStr);
|
|
162
|
+
if (!date)
|
|
163
|
+
return '';
|
|
164
|
+
return date.toLocaleString(undefined, {
|
|
165
|
+
month: 'short',
|
|
166
|
+
day: 'numeric',
|
|
167
|
+
hour: 'numeric',
|
|
168
|
+
minute: '2-digit',
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Color-coded relative age for task rows.
|
|
173
|
+
* Returns a label (e.g. "3d", "2w") and an oklch color string
|
|
174
|
+
* that shifts from green (fresh) → blue → amber → orange → red (stale).
|
|
175
|
+
*
|
|
176
|
+
* Usage:
|
|
177
|
+
* const age = taskAge(task.created_at)
|
|
178
|
+
* // <span style="color: {age.color}">{age.label}</span>
|
|
179
|
+
*/
|
|
180
|
+
export function taskAge(dateStr) {
|
|
181
|
+
var now = Date.now();
|
|
182
|
+
var created = new Date(dateStr).getTime();
|
|
183
|
+
var minutes = Math.floor((now - created) / 60000);
|
|
184
|
+
var hours = Math.floor(minutes / 60);
|
|
185
|
+
var days = Math.floor(hours / 24);
|
|
186
|
+
var weeks = Math.floor(days / 7);
|
|
187
|
+
var months = Math.floor(days / 30);
|
|
188
|
+
if (minutes < 60)
|
|
189
|
+
return { label: "".concat(minutes, "m"), color: 'oklch(0.75 0.18 145)' }; // green — fresh
|
|
190
|
+
if (hours < 24)
|
|
191
|
+
return { label: "".concat(hours, "h"), color: 'oklch(0.75 0.18 145)' }; // green
|
|
192
|
+
if (days < 3)
|
|
193
|
+
return { label: "".concat(days, "d"), color: 'oklch(0.70 0.15 200)' }; // blue — recent
|
|
194
|
+
if (days < 7)
|
|
195
|
+
return { label: "".concat(days, "d"), color: 'oklch(0.75 0.15 85)' }; // amber — aging
|
|
196
|
+
if (weeks < 4)
|
|
197
|
+
return { label: "".concat(weeks, "w"), color: 'oklch(0.65 0.18 50)' }; // orange — stale
|
|
198
|
+
return { label: "".concat(months, "mo"), color: 'oklch(0.65 0.20 25)' }; // red — old
|
|
199
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Centralized Google Maps API loader for jatui.
|
|
3
|
+
*
|
|
4
|
+
* Prevents multiple script loads and ensures all required libraries are available.
|
|
5
|
+
* Pass the API key explicitly — jatui is SvelteKit-agnostic (no $env imports).
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* await loadGoogleMapsAPI({ apiKey: 'YOUR_KEY', libraries: ['marker', 'geometry'] })
|
|
9
|
+
* if (isGoogleMapsLoaded()) { ... }
|
|
10
|
+
*/
|
|
11
|
+
interface LoadOptions {
|
|
12
|
+
apiKey: string;
|
|
13
|
+
libraries?: string[];
|
|
14
|
+
}
|
|
15
|
+
export declare function loadGoogleMapsAPI(options: LoadOptions): Promise<void>;
|
|
16
|
+
export declare function isGoogleMapsLoaded(): boolean;
|
|
17
|
+
export declare function isPlacesLoaded(): boolean;
|
|
18
|
+
export declare function isGeometryLoaded(): boolean;
|
|
19
|
+
export {};
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Centralized Google Maps API loader for jatui.
|
|
3
|
+
*
|
|
4
|
+
* Prevents multiple script loads and ensures all required libraries are available.
|
|
5
|
+
* Pass the API key explicitly — jatui is SvelteKit-agnostic (no $env imports).
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* await loadGoogleMapsAPI({ apiKey: 'YOUR_KEY', libraries: ['marker', 'geometry'] })
|
|
9
|
+
* if (isGoogleMapsLoaded()) { ... }
|
|
10
|
+
*/
|
|
11
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
12
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
13
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
14
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
15
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
16
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
17
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
18
|
+
});
|
|
19
|
+
};
|
|
20
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
21
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
22
|
+
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
23
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
24
|
+
function step(op) {
|
|
25
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
26
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
27
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
28
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
29
|
+
switch (op[0]) {
|
|
30
|
+
case 0: case 1: t = op; break;
|
|
31
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
32
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
33
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
34
|
+
default:
|
|
35
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
36
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
37
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
38
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
39
|
+
if (t[2]) _.ops.pop();
|
|
40
|
+
_.trys.pop(); continue;
|
|
41
|
+
}
|
|
42
|
+
op = body.call(thisArg, _);
|
|
43
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
44
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
48
|
+
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
49
|
+
if (ar || !(i in from)) {
|
|
50
|
+
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
51
|
+
ar[i] = from[i];
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return to.concat(ar || Array.prototype.slice.call(from));
|
|
55
|
+
};
|
|
56
|
+
var loadPromise = null;
|
|
57
|
+
var isLoaded = false;
|
|
58
|
+
export function loadGoogleMapsAPI(options) {
|
|
59
|
+
return __awaiter(this, void 0, Promise, function () {
|
|
60
|
+
var apiKey, _a, libraries, allLibrariesAvailable, allLibraries;
|
|
61
|
+
var _b;
|
|
62
|
+
return __generator(this, function (_c) {
|
|
63
|
+
if (typeof window === 'undefined')
|
|
64
|
+
return [2 /*return*/];
|
|
65
|
+
apiKey = options.apiKey, _a = options.libraries, libraries = _a === void 0 ? [] : _a;
|
|
66
|
+
if (!apiKey) {
|
|
67
|
+
console.warn('googleMapsLoader: No API key provided');
|
|
68
|
+
return [2 /*return*/];
|
|
69
|
+
}
|
|
70
|
+
// If already loaded and all required libraries are available, return
|
|
71
|
+
if (isLoaded && ((_b = window.google) === null || _b === void 0 ? void 0 : _b.maps)) {
|
|
72
|
+
allLibrariesAvailable = libraries.every(function (lib) {
|
|
73
|
+
var _a, _b, _c, _d;
|
|
74
|
+
switch (lib) {
|
|
75
|
+
case 'places':
|
|
76
|
+
return (_b = (_a = window.google) === null || _a === void 0 ? void 0 : _a.maps) === null || _b === void 0 ? void 0 : _b.places;
|
|
77
|
+
case 'geometry':
|
|
78
|
+
return (_d = (_c = window.google) === null || _c === void 0 ? void 0 : _c.maps) === null || _d === void 0 ? void 0 : _d.geometry;
|
|
79
|
+
default:
|
|
80
|
+
return true;
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
if (allLibrariesAvailable)
|
|
84
|
+
return [2 /*return*/];
|
|
85
|
+
}
|
|
86
|
+
// If already loading, return the existing promise
|
|
87
|
+
if (loadPromise)
|
|
88
|
+
return [2 /*return*/, loadPromise];
|
|
89
|
+
allLibraries = Array.from(new Set(__spreadArray(['geometry', 'places', 'marker'], libraries, true)));
|
|
90
|
+
loadPromise = new Promise(function (resolve, reject) {
|
|
91
|
+
var script = document.createElement('script');
|
|
92
|
+
script.src = "https://maps.googleapis.com/maps/api/js?key=".concat(apiKey, "&libraries=").concat(allLibraries.join(','));
|
|
93
|
+
script.async = true;
|
|
94
|
+
script.defer = true;
|
|
95
|
+
script.onload = function () {
|
|
96
|
+
isLoaded = true;
|
|
97
|
+
loadPromise = null;
|
|
98
|
+
resolve();
|
|
99
|
+
};
|
|
100
|
+
script.onerror = function (error) {
|
|
101
|
+
loadPromise = null;
|
|
102
|
+
reject(error);
|
|
103
|
+
};
|
|
104
|
+
document.head.appendChild(script);
|
|
105
|
+
});
|
|
106
|
+
return [2 /*return*/, loadPromise];
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
export function isGoogleMapsLoaded() {
|
|
111
|
+
var _a;
|
|
112
|
+
return isLoaded && !!((_a = window.google) === null || _a === void 0 ? void 0 : _a.maps);
|
|
113
|
+
}
|
|
114
|
+
export function isPlacesLoaded() {
|
|
115
|
+
var _a, _b;
|
|
116
|
+
return isGoogleMapsLoaded() && !!((_b = (_a = window.google) === null || _a === void 0 ? void 0 : _a.maps) === null || _b === void 0 ? void 0 : _b.places);
|
|
117
|
+
}
|
|
118
|
+
export function isGeometryLoaded() {
|
|
119
|
+
var _a, _b;
|
|
120
|
+
return isGoogleMapsLoaded() && !!((_b = (_a = window.google) === null || _a === void 0 ? void 0 : _a.maps) === null || _b === void 0 ? void 0 : _b.geometry);
|
|
121
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mention Parser Utilities
|
|
3
|
+
*
|
|
4
|
+
* Handles parsing and rendering of @-mentions in messages.
|
|
5
|
+
* Format: [@Display Name](type:id) -> clickable links
|
|
6
|
+
*
|
|
7
|
+
* The URL generator is configurable — consuming apps provide their own
|
|
8
|
+
* routing via the `urlGenerator` parameter or by setting a default.
|
|
9
|
+
*/
|
|
10
|
+
export interface MentionMatch {
|
|
11
|
+
type: string;
|
|
12
|
+
id: string;
|
|
13
|
+
displayName: string;
|
|
14
|
+
url: string;
|
|
15
|
+
startIndex: number;
|
|
16
|
+
endIndex: number;
|
|
17
|
+
fullMatch: string;
|
|
18
|
+
}
|
|
19
|
+
export type MentionUrlGenerator = (type: string, id: string) => string;
|
|
20
|
+
/**
|
|
21
|
+
* Set the default URL generator for mentions.
|
|
22
|
+
* Call this once at app startup to configure mention link routing.
|
|
23
|
+
*/
|
|
24
|
+
export declare function setMentionUrlGenerator(generator: MentionUrlGenerator): void;
|
|
25
|
+
/**
|
|
26
|
+
* Parse message content and extract all mentions
|
|
27
|
+
*/
|
|
28
|
+
export declare function parseMentions(content: string, urlGenerator?: MentionUrlGenerator): MentionMatch[];
|
|
29
|
+
/**
|
|
30
|
+
* Convert message content with mentions to HTML
|
|
31
|
+
*/
|
|
32
|
+
export declare function renderMentionsAsHTML(content: string, urlGenerator?: MentionUrlGenerator): string;
|
|
33
|
+
/**
|
|
34
|
+
* Create a mention string for insertion into message input
|
|
35
|
+
*/
|
|
36
|
+
export declare function createMentionString(type: string, id: string, displayName: string): string;
|
|
37
|
+
/**
|
|
38
|
+
* Extract plain text from message content (remove mention markup)
|
|
39
|
+
*/
|
|
40
|
+
export declare function extractPlainText(content: string): string;
|
|
41
|
+
/**
|
|
42
|
+
* Check if cursor is inside a mention
|
|
43
|
+
*/
|
|
44
|
+
export declare function findMentionAtCursor(content: string, cursorPosition: number): MentionMatch | null;
|
|
45
|
+
/**
|
|
46
|
+
* Find @ symbol and following text that could be a mention being typed.
|
|
47
|
+
* Supported symbols: @ $ # ! ~ / +
|
|
48
|
+
*/
|
|
49
|
+
export declare function findPartialMention(content: string, cursorPosition: number): {
|
|
50
|
+
start: number;
|
|
51
|
+
query: string;
|
|
52
|
+
} | null;
|
|
53
|
+
/**
|
|
54
|
+
* Replace partial mention with complete mention string
|
|
55
|
+
*/
|
|
56
|
+
export declare function replaceMentionInContent(content: string, startIndex: number, endIndex: number, mentionString: string): {
|
|
57
|
+
newContent: string;
|
|
58
|
+
newCursorPosition: number;
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* Simple HTML escape function
|
|
62
|
+
*/
|
|
63
|
+
export declare function escapeHTML(text: string): string;
|
|
64
|
+
/**
|
|
65
|
+
* Count mentions in content
|
|
66
|
+
*/
|
|
67
|
+
export declare function countMentions(content: string): number;
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mention Parser Utilities
|
|
3
|
+
*
|
|
4
|
+
* Handles parsing and rendering of @-mentions in messages.
|
|
5
|
+
* Format: [@Display Name](type:id) -> clickable links
|
|
6
|
+
*
|
|
7
|
+
* The URL generator is configurable — consuming apps provide their own
|
|
8
|
+
* routing via the `urlGenerator` parameter or by setting a default.
|
|
9
|
+
*/
|
|
10
|
+
// Regex to match mention pattern: [@Display Name](type:id)
|
|
11
|
+
var MENTION_REGEX = /\[@([^\]]+)\]\(([^:]+):([^)]+)\)/g;
|
|
12
|
+
// Default URL generator (apps can override)
|
|
13
|
+
var defaultUrlGenerator = function (type, id) { return "#".concat(type, "/").concat(id); };
|
|
14
|
+
/**
|
|
15
|
+
* Set the default URL generator for mentions.
|
|
16
|
+
* Call this once at app startup to configure mention link routing.
|
|
17
|
+
*/
|
|
18
|
+
export function setMentionUrlGenerator(generator) {
|
|
19
|
+
defaultUrlGenerator = generator;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Parse message content and extract all mentions
|
|
23
|
+
*/
|
|
24
|
+
export function parseMentions(content, urlGenerator) {
|
|
25
|
+
var mentions = [];
|
|
26
|
+
var gen = urlGenerator !== null && urlGenerator !== void 0 ? urlGenerator : defaultUrlGenerator;
|
|
27
|
+
var match;
|
|
28
|
+
MENTION_REGEX.lastIndex = 0;
|
|
29
|
+
while ((match = MENTION_REGEX.exec(content)) !== null) {
|
|
30
|
+
var fullMatch = match[0], displayName = match[1], type = match[2], id = match[3];
|
|
31
|
+
mentions.push({
|
|
32
|
+
type: type,
|
|
33
|
+
id: id,
|
|
34
|
+
displayName: displayName,
|
|
35
|
+
url: gen(type, id),
|
|
36
|
+
startIndex: match.index,
|
|
37
|
+
endIndex: match.index + fullMatch.length,
|
|
38
|
+
fullMatch: fullMatch
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
return mentions;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Convert message content with mentions to HTML
|
|
45
|
+
*/
|
|
46
|
+
export function renderMentionsAsHTML(content, urlGenerator) {
|
|
47
|
+
var mentions = parseMentions(content, urlGenerator);
|
|
48
|
+
if (mentions.length === 0) {
|
|
49
|
+
return escapeHTML(content);
|
|
50
|
+
}
|
|
51
|
+
var result = '';
|
|
52
|
+
var lastIndex = 0;
|
|
53
|
+
mentions.forEach(function (mention) {
|
|
54
|
+
result += escapeHTML(content.substring(lastIndex, mention.startIndex));
|
|
55
|
+
result += "<a href=\"".concat(mention.url, "\" class=\"mention-link mention-").concat(mention.type, "\" data-mention-type=\"").concat(mention.type, "\" data-mention-id=\"").concat(mention.id, "\">@").concat(escapeHTML(mention.displayName), "</a>");
|
|
56
|
+
lastIndex = mention.endIndex;
|
|
57
|
+
});
|
|
58
|
+
result += escapeHTML(content.substring(lastIndex));
|
|
59
|
+
return result;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Create a mention string for insertion into message input
|
|
63
|
+
*/
|
|
64
|
+
export function createMentionString(type, id, displayName) {
|
|
65
|
+
return "[@".concat(displayName, "](").concat(type, ":").concat(id, ")");
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Extract plain text from message content (remove mention markup)
|
|
69
|
+
*/
|
|
70
|
+
export function extractPlainText(content) {
|
|
71
|
+
MENTION_REGEX.lastIndex = 0;
|
|
72
|
+
return content.replace(MENTION_REGEX, '@$1');
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Check if cursor is inside a mention
|
|
76
|
+
*/
|
|
77
|
+
export function findMentionAtCursor(content, cursorPosition) {
|
|
78
|
+
var mentions = parseMentions(content);
|
|
79
|
+
return (mentions.find(function (mention) { return cursorPosition >= mention.startIndex && cursorPosition <= mention.endIndex; }) || null);
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Find @ symbol and following text that could be a mention being typed.
|
|
83
|
+
* Supported symbols: @ $ # ! ~ / +
|
|
84
|
+
*/
|
|
85
|
+
export function findPartialMention(content, cursorPosition) {
|
|
86
|
+
var mentionSymbols = ['@', '$', '#', '!', '~', '/', '+'];
|
|
87
|
+
var symbolIndex = -1;
|
|
88
|
+
for (var i = cursorPosition - 1; i >= 0; i--) {
|
|
89
|
+
var char = content[i];
|
|
90
|
+
if (mentionSymbols.includes(char)) {
|
|
91
|
+
symbolIndex = i;
|
|
92
|
+
break;
|
|
93
|
+
}
|
|
94
|
+
if (char === ' ' || char === '\n' || char === ']' || char === ')') {
|
|
95
|
+
break;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
if (symbolIndex === -1)
|
|
99
|
+
return null;
|
|
100
|
+
var query = content.substring(symbolIndex + 1, cursorPosition).trim();
|
|
101
|
+
var existingMention = findMentionAtCursor(content, symbolIndex);
|
|
102
|
+
if (existingMention)
|
|
103
|
+
return null;
|
|
104
|
+
return { start: symbolIndex, query: query };
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Replace partial mention with complete mention string
|
|
108
|
+
*/
|
|
109
|
+
export function replaceMentionInContent(content, startIndex, endIndex, mentionString) {
|
|
110
|
+
var before = content.substring(0, startIndex);
|
|
111
|
+
var after = content.substring(endIndex);
|
|
112
|
+
var newContent = before + mentionString + after;
|
|
113
|
+
var newCursorPosition = startIndex + mentionString.length;
|
|
114
|
+
return { newContent: newContent, newCursorPosition: newCursorPosition };
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Simple HTML escape function
|
|
118
|
+
*/
|
|
119
|
+
export function escapeHTML(text) {
|
|
120
|
+
return text
|
|
121
|
+
.replace(/&/g, '&')
|
|
122
|
+
.replace(/</g, '<')
|
|
123
|
+
.replace(/>/g, '>')
|
|
124
|
+
.replace(/"/g, '"')
|
|
125
|
+
.replace(/'/g, ''');
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Count mentions in content
|
|
129
|
+
*/
|
|
130
|
+
export function countMentions(content) {
|
|
131
|
+
return parseMentions(content).length;
|
|
132
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type CountryCode } from "libphonenumber-js";
|
|
2
|
+
export declare const DEFAULT_COUNTRY: CountryCode;
|
|
3
|
+
export declare function toE164(raw: string | null | undefined, defaultCountry?: CountryCode): string | null;
|
|
4
|
+
export declare function formatPhoneForDisplay(e164: string | null | undefined): string;
|
|
5
|
+
export declare function isValidPhone(raw: string | null | undefined, defaultCountry?: CountryCode): boolean;
|
|
6
|
+
export type CountryOption = {
|
|
7
|
+
code: CountryCode;
|
|
8
|
+
name: string;
|
|
9
|
+
dialCode: string;
|
|
10
|
+
flag: string;
|
|
11
|
+
};
|
|
12
|
+
export declare function listCountries(): CountryOption[];
|
|
13
|
+
export declare const PRIORITY_COUNTRIES: CountryCode[];
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { parsePhoneNumberFromString, getCountries, getCountryCallingCode, } from "libphonenumber-js";
|
|
2
|
+
export var DEFAULT_COUNTRY = "US";
|
|
3
|
+
export function toE164(raw, defaultCountry) {
|
|
4
|
+
if (defaultCountry === void 0) { defaultCountry = DEFAULT_COUNTRY; }
|
|
5
|
+
if (!raw)
|
|
6
|
+
return null;
|
|
7
|
+
var trimmed = raw.trim();
|
|
8
|
+
if (!trimmed)
|
|
9
|
+
return null;
|
|
10
|
+
var parsed = parsePhoneNumberFromString(trimmed, defaultCountry);
|
|
11
|
+
if (parsed === null || parsed === void 0 ? void 0 : parsed.isValid())
|
|
12
|
+
return parsed.number;
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
export function formatPhoneForDisplay(e164) {
|
|
16
|
+
if (!e164)
|
|
17
|
+
return "";
|
|
18
|
+
var parsed = parsePhoneNumberFromString(e164);
|
|
19
|
+
if (!parsed)
|
|
20
|
+
return e164;
|
|
21
|
+
return parsed.country === DEFAULT_COUNTRY ? parsed.formatNational() : parsed.formatInternational();
|
|
22
|
+
}
|
|
23
|
+
export function isValidPhone(raw, defaultCountry) {
|
|
24
|
+
var _a;
|
|
25
|
+
if (defaultCountry === void 0) { defaultCountry = DEFAULT_COUNTRY; }
|
|
26
|
+
if (!raw)
|
|
27
|
+
return false;
|
|
28
|
+
var parsed = parsePhoneNumberFromString(raw.trim(), defaultCountry);
|
|
29
|
+
return (_a = parsed === null || parsed === void 0 ? void 0 : parsed.isValid()) !== null && _a !== void 0 ? _a : false;
|
|
30
|
+
}
|
|
31
|
+
var COUNTRY_NAMES = {
|
|
32
|
+
US: "United States", CA: "Canada", GB: "United Kingdom", AU: "Australia", NZ: "New Zealand",
|
|
33
|
+
IE: "Ireland", DE: "Germany", FR: "France", ES: "Spain", IT: "Italy", NL: "Netherlands",
|
|
34
|
+
BE: "Belgium", CH: "Switzerland", AT: "Austria", SE: "Sweden", NO: "Norway", DK: "Denmark",
|
|
35
|
+
FI: "Finland", PT: "Portugal", PL: "Poland", CZ: "Czechia", GR: "Greece", MX: "Mexico",
|
|
36
|
+
BR: "Brazil", AR: "Argentina", CL: "Chile", CO: "Colombia", PE: "Peru", JP: "Japan",
|
|
37
|
+
KR: "South Korea", CN: "China", HK: "Hong Kong", TW: "Taiwan", SG: "Singapore", MY: "Malaysia",
|
|
38
|
+
TH: "Thailand", PH: "Philippines", ID: "Indonesia", VN: "Vietnam", IN: "India", PK: "Pakistan",
|
|
39
|
+
BD: "Bangladesh", IL: "Israel", AE: "UAE", SA: "Saudi Arabia", TR: "Turkey", EG: "Egypt",
|
|
40
|
+
ZA: "South Africa", NG: "Nigeria", KE: "Kenya", RU: "Russia", UA: "Ukraine",
|
|
41
|
+
};
|
|
42
|
+
function flagEmoji(code) {
|
|
43
|
+
return code
|
|
44
|
+
.toUpperCase()
|
|
45
|
+
.split("")
|
|
46
|
+
.map(function (c) { return String.fromCodePoint(127397 + c.charCodeAt(0)); })
|
|
47
|
+
.join("");
|
|
48
|
+
}
|
|
49
|
+
var countriesCache = null;
|
|
50
|
+
export function listCountries() {
|
|
51
|
+
if (countriesCache)
|
|
52
|
+
return countriesCache;
|
|
53
|
+
var all = getCountries()
|
|
54
|
+
.map(function (code) {
|
|
55
|
+
var _a;
|
|
56
|
+
return ({
|
|
57
|
+
code: code,
|
|
58
|
+
name: (_a = COUNTRY_NAMES[code]) !== null && _a !== void 0 ? _a : code,
|
|
59
|
+
dialCode: "+".concat(getCountryCallingCode(code)),
|
|
60
|
+
flag: flagEmoji(code),
|
|
61
|
+
});
|
|
62
|
+
})
|
|
63
|
+
.sort(function (a, b) { return a.name.localeCompare(b.name); });
|
|
64
|
+
countriesCache = all;
|
|
65
|
+
return all;
|
|
66
|
+
}
|
|
67
|
+
export var PRIORITY_COUNTRIES = ["US", "CA", "GB", "AU", "MX"];
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Phone number formatting utilities
|
|
3
|
+
*
|
|
4
|
+
* Provides consistent phone number formatting as (xxx) xxx-xxxx
|
|
5
|
+
* Limits input to 10 digits and handles formatting as user types
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Strips all non-numeric characters from a phone number
|
|
9
|
+
*/
|
|
10
|
+
export declare function stripPhoneNumber(value: string): string;
|
|
11
|
+
/**
|
|
12
|
+
* Formats a phone number to (xxx) xxx-xxxx format
|
|
13
|
+
*/
|
|
14
|
+
export declare function formatPhoneNumber(value: string): string;
|
|
15
|
+
/**
|
|
16
|
+
* Checks if a phone number has exactly 10 digits
|
|
17
|
+
*/
|
|
18
|
+
export declare function isCompletePhoneNumber(value: string): boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Validates phone number format (exactly 10 digits)
|
|
21
|
+
*/
|
|
22
|
+
export declare function isValidPhoneNumber(value: string): boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Handles input formatting with cursor position preservation
|
|
25
|
+
*/
|
|
26
|
+
export declare function updatePhoneInput(input: HTMLInputElement, newValue: string, oldValue: string): void;
|