@aspect-ops/exon-ui 0.0.1 → 0.0.3
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/README.md +438 -0
- package/dist/components/ActionSheet/ActionSheet.svelte +270 -0
- package/dist/components/ActionSheet/ActionSheet.svelte.d.ts +12 -0
- package/dist/components/ActionSheet/ActionSheetItem.svelte +151 -0
- package/dist/components/ActionSheet/ActionSheetItem.svelte.d.ts +10 -0
- package/dist/components/ActionSheet/index.d.ts +3 -0
- package/dist/components/ActionSheet/index.js +2 -0
- package/dist/components/Alert/Alert.svelte +165 -0
- package/dist/components/Alert/Alert.svelte.d.ts +11 -0
- package/dist/components/Alert/index.d.ts +1 -0
- package/dist/components/Alert/index.js +1 -0
- package/dist/components/AspectRatio/AspectRatio.svelte +42 -0
- package/dist/components/AspectRatio/AspectRatio.svelte.d.ts +9 -0
- package/dist/components/AspectRatio/index.d.ts +1 -0
- package/dist/components/AspectRatio/index.js +1 -0
- package/dist/components/Avatar/Avatar.svelte +147 -0
- package/dist/components/Avatar/Avatar.svelte.d.ts +12 -0
- package/dist/components/Avatar/AvatarGroup.svelte +153 -0
- package/dist/components/Avatar/AvatarGroup.svelte.d.ts +12 -0
- package/dist/components/Avatar/index.d.ts +2 -0
- package/dist/components/Avatar/index.js +2 -0
- package/dist/components/BottomSheet/BottomSheet.svelte +230 -0
- package/dist/components/BottomSheet/BottomSheet.svelte.d.ts +7 -0
- package/dist/components/BottomSheet/BottomSheetBody.svelte +20 -0
- package/dist/components/BottomSheet/BottomSheetBody.svelte.d.ts +7 -0
- package/dist/components/BottomSheet/BottomSheetHeader.svelte +27 -0
- package/dist/components/BottomSheet/BottomSheetHeader.svelte.d.ts +7 -0
- package/dist/components/BottomSheet/index.d.ts +3 -0
- package/dist/components/BottomSheet/index.js +3 -0
- package/dist/components/Box/Box.svelte +41 -0
- package/dist/components/Box/Box.svelte.d.ts +7 -0
- package/dist/components/Box/index.d.ts +1 -0
- package/dist/components/Box/index.js +1 -0
- package/dist/components/Card/Card.svelte +95 -0
- package/dist/components/Card/Card.svelte.d.ts +10 -0
- package/dist/components/Card/CardBody.svelte +32 -0
- package/dist/components/Card/CardBody.svelte.d.ts +7 -0
- package/dist/components/Card/CardFooter.svelte +34 -0
- package/dist/components/Card/CardFooter.svelte.d.ts +7 -0
- package/dist/components/Card/CardHeader.svelte +67 -0
- package/dist/components/Card/CardHeader.svelte.d.ts +9 -0
- package/dist/components/Card/index.d.ts +4 -0
- package/dist/components/Card/index.js +4 -0
- package/dist/components/Center/Center.svelte +28 -0
- package/dist/components/Center/Center.svelte.d.ts +8 -0
- package/dist/components/Center/index.d.ts +1 -0
- package/dist/components/Center/index.js +1 -0
- package/dist/components/Container/Container.svelte +58 -0
- package/dist/components/Container/Container.svelte.d.ts +10 -0
- package/dist/components/Container/index.d.ts +1 -0
- package/dist/components/Container/index.js +1 -0
- package/dist/components/Divider/Divider.svelte +38 -0
- package/dist/components/Divider/Divider.svelte.d.ts +9 -0
- package/dist/components/Divider/index.d.ts +1 -0
- package/dist/components/Divider/index.js +1 -0
- package/dist/components/EmptyState/EmptyState.svelte +164 -0
- package/dist/components/EmptyState/EmptyState.svelte.d.ts +12 -0
- package/dist/components/EmptyState/index.d.ts +1 -0
- package/dist/components/EmptyState/index.js +1 -0
- package/dist/components/FAB/FAB.svelte +242 -0
- package/dist/components/FAB/FAB.svelte.d.ts +9 -0
- package/dist/components/FAB/FABGroup.svelte +449 -0
- package/dist/components/FAB/FABGroup.svelte.d.ts +9 -0
- package/dist/components/FAB/index.d.ts +3 -0
- package/dist/components/FAB/index.js +2 -0
- package/dist/components/Grid/Grid.svelte +136 -0
- package/dist/components/Grid/Grid.svelte.d.ts +12 -0
- package/dist/components/Grid/GridItem.svelte +21 -0
- package/dist/components/Grid/GridItem.svelte.d.ts +7 -0
- package/dist/components/Grid/index.d.ts +2 -0
- package/dist/components/Grid/index.js +2 -0
- package/dist/components/List/List.svelte +42 -0
- package/dist/components/List/List.svelte.d.ts +18 -0
- package/dist/components/List/ListItem.svelte +139 -0
- package/dist/components/List/ListItem.svelte.d.ts +36 -0
- package/dist/components/List/index.d.ts +2 -0
- package/dist/components/List/index.js +2 -0
- package/dist/components/Modal/Modal.svelte +204 -0
- package/dist/components/Modal/Modal.svelte.d.ts +7 -0
- package/dist/components/Modal/ModalBody.svelte +50 -0
- package/dist/components/Modal/ModalBody.svelte.d.ts +7 -0
- package/dist/components/Modal/ModalFooter.svelte +37 -0
- package/dist/components/Modal/ModalFooter.svelte.d.ts +7 -0
- package/dist/components/Modal/ModalHeader.svelte +73 -0
- package/dist/components/Modal/ModalHeader.svelte.d.ts +7 -0
- package/dist/components/Modal/index.d.ts +4 -0
- package/dist/components/Modal/index.js +4 -0
- package/dist/components/Popover/Popover.svelte +14 -0
- package/dist/components/Popover/Popover.svelte.d.ts +7 -0
- package/dist/components/Popover/PopoverContent.svelte +63 -0
- package/dist/components/Popover/PopoverContent.svelte.d.ts +7 -0
- package/dist/components/Popover/PopoverTrigger.svelte +14 -0
- package/dist/components/Popover/PopoverTrigger.svelte.d.ts +7 -0
- package/dist/components/Popover/index.d.ts +3 -0
- package/dist/components/Popover/index.js +3 -0
- package/dist/components/Progress/ProgressBar.svelte +86 -0
- package/dist/components/Progress/ProgressBar.svelte.d.ts +11 -0
- package/dist/components/Progress/ProgressCircle.svelte +134 -0
- package/dist/components/Progress/ProgressCircle.svelte.d.ts +12 -0
- package/dist/components/Progress/Spinner.svelte +68 -0
- package/dist/components/Progress/Spinner.svelte.d.ts +8 -0
- package/dist/components/Progress/index.d.ts +3 -0
- package/dist/components/Progress/index.js +3 -0
- package/dist/components/PullToRefresh/PullToRefresh.svelte +304 -0
- package/dist/components/PullToRefresh/PullToRefresh.svelte.d.ts +20 -0
- package/dist/components/PullToRefresh/index.d.ts +1 -0
- package/dist/components/PullToRefresh/index.js +1 -0
- package/dist/components/SafeArea/SafeArea.svelte +33 -0
- package/dist/components/SafeArea/SafeArea.svelte.d.ts +7 -0
- package/dist/components/Select/Select.svelte +55 -12
- package/dist/components/Skeleton/Skeleton.svelte +59 -0
- package/dist/components/Skeleton/Skeleton.svelte.d.ts +10 -0
- package/dist/components/Skeleton/index.d.ts +1 -0
- package/dist/components/Skeleton/index.js +1 -0
- package/dist/components/Spacer/Spacer.svelte +56 -0
- package/dist/components/Spacer/Spacer.svelte.d.ts +6 -0
- package/dist/components/Spacer/index.d.ts +1 -0
- package/dist/components/Spacer/index.js +1 -0
- package/dist/components/Stack/Stack.svelte +117 -0
- package/dist/components/Stack/Stack.svelte.d.ts +13 -0
- package/dist/components/Stack/index.d.ts +1 -0
- package/dist/components/Stack/index.js +1 -0
- package/dist/components/SwipeActions/SwipeAction.svelte +43 -0
- package/dist/components/SwipeActions/SwipeAction.svelte.d.ts +8 -0
- package/dist/components/SwipeActions/SwipeActions.svelte +193 -0
- package/dist/components/SwipeActions/SwipeActions.svelte.d.ts +9 -0
- package/dist/components/SwipeActions/index.d.ts +2 -0
- package/dist/components/SwipeActions/index.js +2 -0
- package/dist/components/Switch/Switch.svelte +29 -9
- package/dist/components/Table/Table.svelte +175 -0
- package/dist/components/Table/Table.svelte.d.ts +38 -0
- package/dist/components/Table/TableBody.svelte +26 -0
- package/dist/components/Table/TableBody.svelte.d.ts +13 -0
- package/dist/components/Table/TableCell.svelte +85 -0
- package/dist/components/Table/TableCell.svelte.d.ts +28 -0
- package/dist/components/Table/TableHead.svelte +36 -0
- package/dist/components/Table/TableHead.svelte.d.ts +13 -0
- package/dist/components/Table/TableHeader.svelte +217 -0
- package/dist/components/Table/TableHeader.svelte.d.ts +32 -0
- package/dist/components/Table/TableRow.svelte +92 -0
- package/dist/components/Table/TableRow.svelte.d.ts +28 -0
- package/dist/components/Table/index.d.ts +6 -0
- package/dist/components/Table/index.js +6 -0
- package/dist/components/Tag/Tag.svelte +189 -0
- package/dist/components/Tag/Tag.svelte.d.ts +13 -0
- package/dist/components/Tag/index.d.ts +1 -0
- package/dist/components/Tag/index.js +1 -0
- package/dist/components/Toast/Toast.svelte +241 -0
- package/dist/components/Toast/Toast.svelte.d.ts +18 -0
- package/dist/components/Toast/ToastContainer.svelte +110 -0
- package/dist/components/Toast/ToastContainer.svelte.d.ts +8 -0
- package/dist/components/Toast/index.d.ts +3 -0
- package/dist/components/Toast/index.js +3 -0
- package/dist/components/Toast/toast.d.ts +13 -0
- package/dist/components/Toast/toast.js +55 -0
- package/dist/components/Tooltip/Tooltip.svelte +71 -0
- package/dist/components/Tooltip/Tooltip.svelte.d.ts +7 -0
- package/dist/components/Tooltip/index.d.ts +2 -0
- package/dist/components/Tooltip/index.js +1 -0
- package/dist/index.d.ts +29 -1
- package/dist/index.js +32 -0
- package/dist/styles/tokens.css +5 -0
- package/dist/types/data-display.d.ts +93 -0
- package/dist/types/data-display.js +1 -0
- package/dist/types/feedback.d.ts +92 -0
- package/dist/types/feedback.js +1 -0
- package/dist/types/index.d.ts +4 -0
- package/dist/types/layout.d.ts +57 -0
- package/dist/types/layout.js +1 -0
- package/dist/types/mobile.d.ts +91 -0
- package/dist/types/mobile.js +1 -0
- package/dist/utils/gestures.d.ts +219 -0
- package/dist/utils/gestures.js +492 -0
- package/dist/utils/haptics.d.ts +89 -0
- package/dist/utils/haptics.js +198 -0
- package/dist/utils/platform.d.ts +47 -0
- package/dist/utils/platform.js +156 -0
- package/package.json +1 -1
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Haptics Utility - Cross-platform haptic feedback wrapper
|
|
3
|
+
*
|
|
4
|
+
* Wraps Capacitor Haptics with graceful web fallback (no-op on web).
|
|
5
|
+
* Uses optional peer dependency pattern - works without @capacitor/haptics installed.
|
|
6
|
+
* All functions are async and never throw - errors are caught silently.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Triggers impact haptic feedback.
|
|
10
|
+
*
|
|
11
|
+
* @param style - Impact intensity: 'light', 'medium', or 'heavy'
|
|
12
|
+
* @returns Promise that resolves when haptic is complete (or immediately on web)
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* // Light tap feedback
|
|
17
|
+
* await hapticImpact('light');
|
|
18
|
+
*
|
|
19
|
+
* // Heavy impact for important actions
|
|
20
|
+
* await hapticImpact('heavy');
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export declare function hapticImpact(style: 'light' | 'medium' | 'heavy'): Promise<void>;
|
|
24
|
+
/**
|
|
25
|
+
* Triggers notification haptic feedback.
|
|
26
|
+
*
|
|
27
|
+
* @param type - Notification type: 'success', 'warning', or 'error'
|
|
28
|
+
* @returns Promise that resolves when haptic is complete (or immediately on web)
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```typescript
|
|
32
|
+
* // Success feedback after form submission
|
|
33
|
+
* await hapticNotification('success');
|
|
34
|
+
*
|
|
35
|
+
* // Warning feedback for validation issues
|
|
36
|
+
* await hapticNotification('warning');
|
|
37
|
+
*
|
|
38
|
+
* // Error feedback for failures
|
|
39
|
+
* await hapticNotification('error');
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
export declare function hapticNotification(type: 'success' | 'warning' | 'error'): Promise<void>;
|
|
43
|
+
/**
|
|
44
|
+
* Triggers selection change haptic feedback.
|
|
45
|
+
* Use this for UI selection changes like picker scrolling or toggle switches.
|
|
46
|
+
*
|
|
47
|
+
* @returns Promise that resolves when haptic is complete (or immediately on web)
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* ```typescript
|
|
51
|
+
* // Feedback when user changes selection
|
|
52
|
+
* function onSelectionChange(value: string) {
|
|
53
|
+
* await hapticSelection();
|
|
54
|
+
* setSelected(value);
|
|
55
|
+
* }
|
|
56
|
+
* ```
|
|
57
|
+
*/
|
|
58
|
+
export declare function hapticSelection(): Promise<void>;
|
|
59
|
+
/**
|
|
60
|
+
* Triggers a simple vibration.
|
|
61
|
+
*
|
|
62
|
+
* @param duration - Vibration duration in milliseconds (default: 300ms)
|
|
63
|
+
* @returns Promise that resolves when vibration is complete (or immediately on web)
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* ```typescript
|
|
67
|
+
* // Default vibration
|
|
68
|
+
* await hapticVibrate();
|
|
69
|
+
*
|
|
70
|
+
* // Custom duration vibration
|
|
71
|
+
* await hapticVibrate(500);
|
|
72
|
+
* ```
|
|
73
|
+
*/
|
|
74
|
+
export declare function hapticVibrate(duration?: number): Promise<void>;
|
|
75
|
+
/**
|
|
76
|
+
* Checks if haptics are available on the current platform.
|
|
77
|
+
* Useful for conditional UI that depends on haptic support.
|
|
78
|
+
*
|
|
79
|
+
* @returns Promise<boolean> - true if haptics are available
|
|
80
|
+
*
|
|
81
|
+
* @example
|
|
82
|
+
* ```typescript
|
|
83
|
+
* const hasHaptics = await isHapticsAvailable();
|
|
84
|
+
* if (hasHaptics) {
|
|
85
|
+
* showHapticSettings();
|
|
86
|
+
* }
|
|
87
|
+
* ```
|
|
88
|
+
*/
|
|
89
|
+
export declare function isHapticsAvailable(): Promise<boolean>;
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Haptics Utility - Cross-platform haptic feedback wrapper
|
|
3
|
+
*
|
|
4
|
+
* Wraps Capacitor Haptics with graceful web fallback (no-op on web).
|
|
5
|
+
* Uses optional peer dependency pattern - works without @capacitor/haptics installed.
|
|
6
|
+
* All functions are async and never throw - errors are caught silently.
|
|
7
|
+
*/
|
|
8
|
+
// Cached Haptics module reference
|
|
9
|
+
let hapticsModule = null;
|
|
10
|
+
let hapticsLoaded = false;
|
|
11
|
+
let hapticsAvailable = false;
|
|
12
|
+
/**
|
|
13
|
+
* Checks if we're running in a Capacitor native environment
|
|
14
|
+
*/
|
|
15
|
+
function isCapacitorNative() {
|
|
16
|
+
if (typeof window === 'undefined')
|
|
17
|
+
return false;
|
|
18
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
19
|
+
const cap = window.Capacitor;
|
|
20
|
+
return cap?.isNativePlatform?.() ?? false;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Attempts to load the Capacitor Haptics module.
|
|
24
|
+
* Only attempts import in Capacitor native environment to avoid Vite build errors.
|
|
25
|
+
* Caches the result to avoid repeated dynamic imports.
|
|
26
|
+
*/
|
|
27
|
+
async function getHaptics() {
|
|
28
|
+
if (hapticsLoaded) {
|
|
29
|
+
return hapticsModule;
|
|
30
|
+
}
|
|
31
|
+
// Only attempt to load haptics in native Capacitor environment
|
|
32
|
+
if (!isCapacitorNative()) {
|
|
33
|
+
hapticsLoaded = true;
|
|
34
|
+
hapticsModule = null;
|
|
35
|
+
hapticsAvailable = false;
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
try {
|
|
39
|
+
// Dynamic import with variable to prevent Vite static analysis
|
|
40
|
+
const modulePath = '@capacitor/haptics';
|
|
41
|
+
const module = await import(/* @vite-ignore */ modulePath);
|
|
42
|
+
hapticsModule = module.Haptics;
|
|
43
|
+
hapticsAvailable = true;
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
// @capacitor/haptics not installed or import failed
|
|
47
|
+
hapticsModule = null;
|
|
48
|
+
hapticsAvailable = false;
|
|
49
|
+
}
|
|
50
|
+
hapticsLoaded = true;
|
|
51
|
+
return hapticsModule;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Style mapping from simple strings to Capacitor ImpactStyle values
|
|
55
|
+
*/
|
|
56
|
+
const impactStyleMap = {
|
|
57
|
+
light: 'Light',
|
|
58
|
+
medium: 'Medium',
|
|
59
|
+
heavy: 'Heavy'
|
|
60
|
+
};
|
|
61
|
+
/**
|
|
62
|
+
* Type mapping from simple strings to Capacitor NotificationType values
|
|
63
|
+
*/
|
|
64
|
+
const notificationTypeMap = {
|
|
65
|
+
success: 'Success',
|
|
66
|
+
warning: 'Warning',
|
|
67
|
+
error: 'Error'
|
|
68
|
+
};
|
|
69
|
+
/**
|
|
70
|
+
* Triggers impact haptic feedback.
|
|
71
|
+
*
|
|
72
|
+
* @param style - Impact intensity: 'light', 'medium', or 'heavy'
|
|
73
|
+
* @returns Promise that resolves when haptic is complete (or immediately on web)
|
|
74
|
+
*
|
|
75
|
+
* @example
|
|
76
|
+
* ```typescript
|
|
77
|
+
* // Light tap feedback
|
|
78
|
+
* await hapticImpact('light');
|
|
79
|
+
*
|
|
80
|
+
* // Heavy impact for important actions
|
|
81
|
+
* await hapticImpact('heavy');
|
|
82
|
+
* ```
|
|
83
|
+
*/
|
|
84
|
+
export async function hapticImpact(style) {
|
|
85
|
+
try {
|
|
86
|
+
const haptics = await getHaptics();
|
|
87
|
+
if (haptics) {
|
|
88
|
+
await haptics.impact({ style: impactStyleMap[style] });
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
// Silently ignore errors - haptics should never break functionality
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Triggers notification haptic feedback.
|
|
97
|
+
*
|
|
98
|
+
* @param type - Notification type: 'success', 'warning', or 'error'
|
|
99
|
+
* @returns Promise that resolves when haptic is complete (or immediately on web)
|
|
100
|
+
*
|
|
101
|
+
* @example
|
|
102
|
+
* ```typescript
|
|
103
|
+
* // Success feedback after form submission
|
|
104
|
+
* await hapticNotification('success');
|
|
105
|
+
*
|
|
106
|
+
* // Warning feedback for validation issues
|
|
107
|
+
* await hapticNotification('warning');
|
|
108
|
+
*
|
|
109
|
+
* // Error feedback for failures
|
|
110
|
+
* await hapticNotification('error');
|
|
111
|
+
* ```
|
|
112
|
+
*/
|
|
113
|
+
export async function hapticNotification(type) {
|
|
114
|
+
try {
|
|
115
|
+
const haptics = await getHaptics();
|
|
116
|
+
if (haptics) {
|
|
117
|
+
await haptics.notification({ type: notificationTypeMap[type] });
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
catch {
|
|
121
|
+
// Silently ignore errors - haptics should never break functionality
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Triggers selection change haptic feedback.
|
|
126
|
+
* Use this for UI selection changes like picker scrolling or toggle switches.
|
|
127
|
+
*
|
|
128
|
+
* @returns Promise that resolves when haptic is complete (or immediately on web)
|
|
129
|
+
*
|
|
130
|
+
* @example
|
|
131
|
+
* ```typescript
|
|
132
|
+
* // Feedback when user changes selection
|
|
133
|
+
* function onSelectionChange(value: string) {
|
|
134
|
+
* await hapticSelection();
|
|
135
|
+
* setSelected(value);
|
|
136
|
+
* }
|
|
137
|
+
* ```
|
|
138
|
+
*/
|
|
139
|
+
export async function hapticSelection() {
|
|
140
|
+
try {
|
|
141
|
+
const haptics = await getHaptics();
|
|
142
|
+
if (haptics) {
|
|
143
|
+
await haptics.selectionChanged();
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
catch {
|
|
147
|
+
// Silently ignore errors - haptics should never break functionality
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Triggers a simple vibration.
|
|
152
|
+
*
|
|
153
|
+
* @param duration - Vibration duration in milliseconds (default: 300ms)
|
|
154
|
+
* @returns Promise that resolves when vibration is complete (or immediately on web)
|
|
155
|
+
*
|
|
156
|
+
* @example
|
|
157
|
+
* ```typescript
|
|
158
|
+
* // Default vibration
|
|
159
|
+
* await hapticVibrate();
|
|
160
|
+
*
|
|
161
|
+
* // Custom duration vibration
|
|
162
|
+
* await hapticVibrate(500);
|
|
163
|
+
* ```
|
|
164
|
+
*/
|
|
165
|
+
export async function hapticVibrate(duration = 300) {
|
|
166
|
+
try {
|
|
167
|
+
const haptics = await getHaptics();
|
|
168
|
+
if (haptics) {
|
|
169
|
+
await haptics.vibrate({ duration });
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
catch {
|
|
173
|
+
// Silently ignore errors - haptics should never break functionality
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Checks if haptics are available on the current platform.
|
|
178
|
+
* Useful for conditional UI that depends on haptic support.
|
|
179
|
+
*
|
|
180
|
+
* @returns Promise<boolean> - true if haptics are available
|
|
181
|
+
*
|
|
182
|
+
* @example
|
|
183
|
+
* ```typescript
|
|
184
|
+
* const hasHaptics = await isHapticsAvailable();
|
|
185
|
+
* if (hasHaptics) {
|
|
186
|
+
* showHapticSettings();
|
|
187
|
+
* }
|
|
188
|
+
* ```
|
|
189
|
+
*/
|
|
190
|
+
export async function isHapticsAvailable() {
|
|
191
|
+
try {
|
|
192
|
+
await getHaptics();
|
|
193
|
+
return hapticsAvailable;
|
|
194
|
+
}
|
|
195
|
+
catch {
|
|
196
|
+
return false;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Platform Detection Utility
|
|
3
|
+
* Detects the current platform (iOS, Android, or Web) using Capacitor when available.
|
|
4
|
+
* Provides graceful fallback when Capacitor is not installed or not running in a native context.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Supported platform types
|
|
8
|
+
*/
|
|
9
|
+
export type Platform = 'ios' | 'android' | 'web';
|
|
10
|
+
/**
|
|
11
|
+
* Initialize platform detection asynchronously
|
|
12
|
+
* Call this early in your app lifecycle for most accurate detection
|
|
13
|
+
* @returns Promise that resolves when platform is detected
|
|
14
|
+
*/
|
|
15
|
+
export declare function initPlatform(): Promise<Platform>;
|
|
16
|
+
/**
|
|
17
|
+
* Get the current platform
|
|
18
|
+
* Returns immediately with best available detection (may use sync fallback)
|
|
19
|
+
* For guaranteed accuracy, call initPlatform() first and await it
|
|
20
|
+
* @returns The detected platform
|
|
21
|
+
*/
|
|
22
|
+
export declare function getPlatform(): Platform;
|
|
23
|
+
/**
|
|
24
|
+
* Check if running on iOS
|
|
25
|
+
* @returns true if the current platform is iOS
|
|
26
|
+
*/
|
|
27
|
+
export declare function isIOS(): boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Check if running on Android
|
|
30
|
+
* @returns true if the current platform is Android
|
|
31
|
+
*/
|
|
32
|
+
export declare function isAndroid(): boolean;
|
|
33
|
+
/**
|
|
34
|
+
* Check if running as a native app (iOS or Android)
|
|
35
|
+
* @returns true if running in a native Capacitor context
|
|
36
|
+
*/
|
|
37
|
+
export declare function isNative(): boolean;
|
|
38
|
+
/**
|
|
39
|
+
* Check if running on web (browser without native wrapper)
|
|
40
|
+
* @returns true if running in a standard web browser
|
|
41
|
+
*/
|
|
42
|
+
export declare function isWeb(): boolean;
|
|
43
|
+
/**
|
|
44
|
+
* Reset platform detection (useful for testing)
|
|
45
|
+
* @internal
|
|
46
|
+
*/
|
|
47
|
+
export declare function _resetPlatform(): void;
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Platform Detection Utility
|
|
3
|
+
* Detects the current platform (iOS, Android, or Web) using Capacitor when available.
|
|
4
|
+
* Provides graceful fallback when Capacitor is not installed or not running in a native context.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Internal state - initialized lazily on first access
|
|
8
|
+
*/
|
|
9
|
+
let _platform = 'web';
|
|
10
|
+
let _initialized = false;
|
|
11
|
+
/**
|
|
12
|
+
* Initialize platform detection
|
|
13
|
+
* Uses dynamic import to gracefully handle cases where @capacitor/core is not installed
|
|
14
|
+
*/
|
|
15
|
+
async function initializePlatform() {
|
|
16
|
+
if (_initialized)
|
|
17
|
+
return;
|
|
18
|
+
try {
|
|
19
|
+
// Dynamic import to handle cases where Capacitor is not installed
|
|
20
|
+
const capacitorModule = (await import('@capacitor/core'));
|
|
21
|
+
const Capacitor = capacitorModule.Capacitor;
|
|
22
|
+
if (Capacitor && typeof Capacitor.getPlatform === 'function') {
|
|
23
|
+
const detectedPlatform = Capacitor.getPlatform();
|
|
24
|
+
if (detectedPlatform === 'ios' ||
|
|
25
|
+
detectedPlatform === 'android' ||
|
|
26
|
+
detectedPlatform === 'web') {
|
|
27
|
+
_platform = detectedPlatform;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
// Capacitor not available - default to 'web'
|
|
33
|
+
_platform = 'web';
|
|
34
|
+
}
|
|
35
|
+
_initialized = true;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Synchronous platform detection using user agent as fallback
|
|
39
|
+
* This is used for immediate platform detection without async initialization
|
|
40
|
+
*/
|
|
41
|
+
function detectPlatformSync() {
|
|
42
|
+
if (_initialized)
|
|
43
|
+
return _platform;
|
|
44
|
+
// Check if running in browser environment
|
|
45
|
+
if (typeof window === 'undefined' || typeof navigator === 'undefined') {
|
|
46
|
+
return 'web';
|
|
47
|
+
}
|
|
48
|
+
// Try synchronous Capacitor detection first
|
|
49
|
+
try {
|
|
50
|
+
// Check for Capacitor global (may be available if loaded synchronously)
|
|
51
|
+
const win = window;
|
|
52
|
+
if (win.Capacitor && typeof win.Capacitor.getPlatform === 'function') {
|
|
53
|
+
const detectedPlatform = win.Capacitor.getPlatform();
|
|
54
|
+
if (detectedPlatform === 'ios' ||
|
|
55
|
+
detectedPlatform === 'android' ||
|
|
56
|
+
detectedPlatform === 'web') {
|
|
57
|
+
_platform = detectedPlatform;
|
|
58
|
+
_initialized = true;
|
|
59
|
+
return _platform;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
// Capacitor not available synchronously
|
|
65
|
+
}
|
|
66
|
+
// Fallback to user agent detection for native webviews
|
|
67
|
+
const userAgent = navigator.userAgent.toLowerCase();
|
|
68
|
+
// Check for iOS (iPhone, iPad, iPod)
|
|
69
|
+
if (/iphone|ipad|ipod/.test(userAgent)) {
|
|
70
|
+
// Additional check for native iOS app context
|
|
71
|
+
const isNativeIOS = /capacitor|ionic|cordova/.test(userAgent) ||
|
|
72
|
+
window.webkit?.messageHandlers !==
|
|
73
|
+
undefined;
|
|
74
|
+
if (isNativeIOS) {
|
|
75
|
+
_platform = 'ios';
|
|
76
|
+
_initialized = true;
|
|
77
|
+
return _platform;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
// Check for Android
|
|
81
|
+
if (/android/.test(userAgent)) {
|
|
82
|
+
// Additional check for native Android app context
|
|
83
|
+
const isNativeAndroid = /capacitor|ionic|cordova/.test(userAgent) ||
|
|
84
|
+
window.AndroidBridge !== undefined;
|
|
85
|
+
if (isNativeAndroid) {
|
|
86
|
+
_platform = 'android';
|
|
87
|
+
_initialized = true;
|
|
88
|
+
return _platform;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
// Default to web
|
|
92
|
+
_platform = 'web';
|
|
93
|
+
_initialized = true;
|
|
94
|
+
return _platform;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Initialize platform detection asynchronously
|
|
98
|
+
* Call this early in your app lifecycle for most accurate detection
|
|
99
|
+
* @returns Promise that resolves when platform is detected
|
|
100
|
+
*/
|
|
101
|
+
export async function initPlatform() {
|
|
102
|
+
await initializePlatform();
|
|
103
|
+
return _platform;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Get the current platform
|
|
107
|
+
* Returns immediately with best available detection (may use sync fallback)
|
|
108
|
+
* For guaranteed accuracy, call initPlatform() first and await it
|
|
109
|
+
* @returns The detected platform
|
|
110
|
+
*/
|
|
111
|
+
export function getPlatform() {
|
|
112
|
+
if (!_initialized) {
|
|
113
|
+
// Use sync detection for immediate response
|
|
114
|
+
detectPlatformSync();
|
|
115
|
+
// Also kick off async detection for future calls
|
|
116
|
+
initializePlatform();
|
|
117
|
+
}
|
|
118
|
+
return _platform;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Check if running on iOS
|
|
122
|
+
* @returns true if the current platform is iOS
|
|
123
|
+
*/
|
|
124
|
+
export function isIOS() {
|
|
125
|
+
return getPlatform() === 'ios';
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Check if running on Android
|
|
129
|
+
* @returns true if the current platform is Android
|
|
130
|
+
*/
|
|
131
|
+
export function isAndroid() {
|
|
132
|
+
return getPlatform() === 'android';
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Check if running as a native app (iOS or Android)
|
|
136
|
+
* @returns true if running in a native Capacitor context
|
|
137
|
+
*/
|
|
138
|
+
export function isNative() {
|
|
139
|
+
const platform = getPlatform();
|
|
140
|
+
return platform === 'ios' || platform === 'android';
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Check if running on web (browser without native wrapper)
|
|
144
|
+
* @returns true if running in a standard web browser
|
|
145
|
+
*/
|
|
146
|
+
export function isWeb() {
|
|
147
|
+
return getPlatform() === 'web';
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Reset platform detection (useful for testing)
|
|
151
|
+
* @internal
|
|
152
|
+
*/
|
|
153
|
+
export function _resetPlatform() {
|
|
154
|
+
_platform = 'web';
|
|
155
|
+
_initialized = false;
|
|
156
|
+
}
|