@harkenapp/sdk-react-native 0.0.1-alpha.1 → 0.0.1-alpha.2
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 +44 -7
- package/app.plugin.cjs +12 -17
- package/dist/__mocks__/async-storage.d.ts +16 -0
- package/dist/__mocks__/async-storage.d.ts.map +1 -0
- package/dist/__mocks__/async-storage.js +39 -0
- package/dist/__mocks__/async-storage.js.map +1 -0
- package/dist/__mocks__/expo-document-picker.d.ts +26 -0
- package/dist/__mocks__/expo-document-picker.d.ts.map +1 -0
- package/dist/__mocks__/expo-document-picker.js +25 -0
- package/dist/__mocks__/expo-document-picker.js.map +1 -0
- package/dist/__mocks__/expo-file-system.d.ts +42 -0
- package/dist/__mocks__/expo-file-system.d.ts.map +1 -0
- package/dist/__mocks__/expo-file-system.js +37 -0
- package/dist/__mocks__/expo-file-system.js.map +1 -0
- package/dist/__mocks__/expo-image-picker.d.ts +30 -0
- package/dist/__mocks__/expo-image-picker.d.ts.map +1 -0
- package/dist/__mocks__/expo-image-picker.js +30 -0
- package/dist/__mocks__/expo-image-picker.js.map +1 -0
- package/dist/__mocks__/expo-secure-store.d.ts +15 -0
- package/dist/__mocks__/expo-secure-store.d.ts.map +1 -0
- package/dist/__mocks__/expo-secure-store.js +30 -0
- package/dist/__mocks__/expo-secure-store.js.map +1 -0
- package/dist/__mocks__/react-native.d.ts +73 -0
- package/dist/__mocks__/react-native.d.ts.map +1 -0
- package/dist/__mocks__/react-native.js +45 -0
- package/dist/__mocks__/react-native.js.map +1 -0
- package/dist/api/client.d.ts +8 -8
- package/dist/api/client.d.ts.map +1 -1
- package/dist/api/client.js +17 -19
- package/dist/api/client.js.map +1 -1
- package/dist/api/client.test.d.ts +2 -0
- package/dist/api/client.test.d.ts.map +1 -0
- package/dist/api/client.test.js +417 -0
- package/dist/api/client.test.js.map +1 -0
- package/dist/api/errors.d.ts +3 -3
- package/dist/api/errors.d.ts.map +1 -1
- package/dist/api/errors.js +3 -3
- package/dist/api/errors.js.map +1 -1
- package/dist/api/errors.test.d.ts +2 -0
- package/dist/api/errors.test.d.ts.map +1 -0
- package/dist/api/errors.test.js +155 -0
- package/dist/api/errors.test.js.map +1 -0
- package/dist/api/index.d.ts +6 -6
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/index.js.map +1 -1
- package/dist/api/retry.d.ts +1 -1
- package/dist/api/retry.d.ts.map +1 -1
- package/dist/api/retry.js.map +1 -1
- package/dist/api/retry.test.d.ts +2 -0
- package/dist/api/retry.test.d.ts.map +1 -0
- package/dist/api/retry.test.js +193 -0
- package/dist/api/retry.test.js.map +1 -0
- package/dist/attachments/FeedbackSheet.d.ts +36 -13
- package/dist/attachments/FeedbackSheet.d.ts.map +1 -1
- package/dist/attachments/FeedbackSheet.js +50 -30
- package/dist/attachments/FeedbackSheet.js.map +1 -1
- package/dist/attachments/index.d.ts +2 -2
- package/dist/components/AttachmentGrid.d.ts +12 -4
- package/dist/components/AttachmentGrid.d.ts.map +1 -1
- package/dist/components/AttachmentGrid.js +44 -34
- package/dist/components/AttachmentGrid.js.map +1 -1
- package/dist/components/AttachmentPicker.d.ts +3 -3
- package/dist/components/AttachmentPicker.d.ts.map +1 -1
- package/dist/components/AttachmentPicker.js +34 -36
- package/dist/components/AttachmentPicker.js.map +1 -1
- package/dist/components/AttachmentPreview.d.ts +10 -4
- package/dist/components/AttachmentPreview.d.ts.map +1 -1
- package/dist/components/AttachmentPreview.js +48 -34
- package/dist/components/AttachmentPreview.js.map +1 -1
- package/dist/components/CategorySelector.d.ts +3 -3
- package/dist/components/CategorySelector.d.ts.map +1 -1
- package/dist/components/CategorySelector.js +21 -27
- package/dist/components/CategorySelector.js.map +1 -1
- package/dist/components/FeedbackForm.d.ts +3 -3
- package/dist/components/FeedbackForm.d.ts.map +1 -1
- package/dist/components/FeedbackForm.js +7 -8
- package/dist/components/FeedbackForm.js.map +1 -1
- package/dist/components/FeedbackSheet.d.ts +34 -11
- package/dist/components/FeedbackSheet.d.ts.map +1 -1
- package/dist/components/FeedbackSheet.js +46 -28
- package/dist/components/FeedbackSheet.js.map +1 -1
- package/dist/components/ThemedButton.d.ts +16 -5
- package/dist/components/ThemedButton.d.ts.map +1 -1
- package/dist/components/ThemedButton.js +38 -29
- package/dist/components/ThemedButton.js.map +1 -1
- package/dist/components/ThemedText.d.ts +3 -3
- package/dist/components/ThemedText.d.ts.map +1 -1
- package/dist/components/ThemedText.js +1 -1
- package/dist/components/ThemedText.js.map +1 -1
- package/dist/components/ThemedTextInput.d.ts +11 -2
- package/dist/components/ThemedTextInput.d.ts.map +1 -1
- package/dist/components/ThemedTextInput.js +19 -9
- package/dist/components/ThemedTextInput.js.map +1 -1
- package/dist/components/UploadStatusOverlay.d.ts +11 -3
- package/dist/components/UploadStatusOverlay.d.ts.map +1 -1
- package/dist/components/UploadStatusOverlay.js +59 -76
- package/dist/components/UploadStatusOverlay.js.map +1 -1
- package/dist/components/index.d.ts +18 -18
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js.map +1 -1
- package/dist/context/HarkenContext.d.ts +20 -15
- package/dist/context/HarkenContext.d.ts.map +1 -1
- package/dist/context/HarkenContext.js +20 -17
- package/dist/context/HarkenContext.js.map +1 -1
- package/dist/context/index.d.ts +2 -2
- package/dist/domain/index.d.ts +2 -2
- package/dist/domain/index.d.ts.map +1 -1
- package/dist/domain/index.js.map +1 -1
- package/dist/hooks/index.d.ts +5 -5
- package/dist/hooks/useAnonymousId.js +1 -1
- package/dist/hooks/useAnonymousId.test.d.ts +2 -0
- package/dist/hooks/useAnonymousId.test.d.ts.map +1 -0
- package/dist/hooks/useAnonymousId.test.js +154 -0
- package/dist/hooks/useAnonymousId.test.js.map +1 -0
- package/dist/hooks/useAttachmentPicker.d.ts +3 -3
- package/dist/hooks/useAttachmentPicker.js +7 -7
- package/dist/hooks/useAttachmentStatus.d.ts +1 -1
- package/dist/hooks/useAttachmentStatus.d.ts.map +1 -1
- package/dist/hooks/useAttachmentStatus.js.map +1 -1
- package/dist/hooks/useAttachmentUpload.d.ts +2 -2
- package/dist/hooks/useAttachmentUpload.d.ts.map +1 -1
- package/dist/hooks/useAttachmentUpload.js +5 -5
- package/dist/hooks/useAttachmentUpload.js.map +1 -1
- package/dist/hooks/useAttachmentUpload.test.d.ts +2 -0
- package/dist/hooks/useAttachmentUpload.test.d.ts.map +1 -0
- package/dist/hooks/useAttachmentUpload.test.js +542 -0
- package/dist/hooks/useAttachmentUpload.test.js.map +1 -0
- package/dist/hooks/useFeedback.d.ts +4 -4
- package/dist/hooks/useFeedback.d.ts.map +1 -1
- package/dist/hooks/useFeedback.js +3 -5
- package/dist/hooks/useFeedback.js.map +1 -1
- package/dist/hooks/useFeedback.test.d.ts +2 -0
- package/dist/hooks/useFeedback.test.d.ts.map +1 -0
- package/dist/hooks/useFeedback.test.js +299 -0
- package/dist/hooks/useFeedback.test.js.map +1 -0
- package/dist/hooks/useHarkenContext.d.ts +1 -1
- package/dist/hooks/useHarkenContext.js +1 -1
- package/dist/hooks/useHarkenTheme.d.ts +27 -3
- package/dist/hooks/useHarkenTheme.d.ts.map +1 -1
- package/dist/hooks/useHarkenTheme.js +26 -2
- package/dist/hooks/useHarkenTheme.js.map +1 -1
- package/dist/index.d.ts +28 -28
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/services/index.d.ts +3 -3
- package/dist/services/index.d.ts.map +1 -1
- package/dist/services/index.js.map +1 -1
- package/dist/services/uploadQueueService.d.ts +2 -2
- package/dist/services/uploadQueueService.d.ts.map +1 -1
- package/dist/services/uploadQueueService.js +16 -17
- package/dist/services/uploadQueueService.js.map +1 -1
- package/dist/services/uploadQueueService.test.d.ts +2 -0
- package/dist/services/uploadQueueService.test.d.ts.map +1 -0
- package/dist/services/uploadQueueService.test.js +426 -0
- package/dist/services/uploadQueueService.test.js.map +1 -0
- package/dist/services/uploadQueueStorage.d.ts +1 -1
- package/dist/services/uploadQueueStorage.d.ts.map +1 -1
- package/dist/services/uploadQueueStorage.js +4 -4
- package/dist/services/uploadQueueStorage.js.map +1 -1
- package/dist/services/uploadQueueStorage.test.d.ts +2 -0
- package/dist/services/uploadQueueStorage.test.d.ts.map +1 -0
- package/dist/services/uploadQueueStorage.test.js +200 -0
- package/dist/services/uploadQueueStorage.test.js.map +1 -0
- package/dist/storage/IdentityStore.d.ts +1 -1
- package/dist/storage/IdentityStore.d.ts.map +1 -1
- package/dist/storage/IdentityStore.js.map +1 -1
- package/dist/storage/IdentityStore.test.d.ts +2 -0
- package/dist/storage/IdentityStore.test.d.ts.map +1 -0
- package/dist/storage/IdentityStore.test.js +176 -0
- package/dist/storage/IdentityStore.test.js.map +1 -0
- package/dist/storage/SecureStoreAdapter.d.ts +1 -1
- package/dist/storage/SecureStoreAdapter.test.d.ts +2 -0
- package/dist/storage/SecureStoreAdapter.test.d.ts.map +1 -0
- package/dist/storage/SecureStoreAdapter.test.js +114 -0
- package/dist/storage/SecureStoreAdapter.test.js.map +1 -0
- package/dist/storage/defaultStorage.d.ts +1 -1
- package/dist/storage/defaultStorage.js +4 -4
- package/dist/storage/defaultStorage.test.d.ts +2 -0
- package/dist/storage/defaultStorage.test.d.ts.map +1 -0
- package/dist/storage/defaultStorage.test.js +159 -0
- package/dist/storage/defaultStorage.test.js.map +1 -0
- package/dist/storage/index.d.ts +5 -5
- package/dist/storage/types.js +1 -1
- package/dist/theme/defaults.d.ts +14 -3
- package/dist/theme/defaults.d.ts.map +1 -1
- package/dist/theme/defaults.js +58 -43
- package/dist/theme/defaults.js.map +1 -1
- package/dist/theme/index.d.ts +3 -2
- package/dist/theme/index.d.ts.map +1 -1
- package/dist/theme/index.js +4 -1
- package/dist/theme/index.js.map +1 -1
- package/dist/theme/resolver.d.ts +16 -0
- package/dist/theme/resolver.d.ts.map +1 -0
- package/dist/theme/resolver.js +375 -0
- package/dist/theme/resolver.js.map +1 -0
- package/dist/theme/resolver.test.d.ts +2 -0
- package/dist/theme/resolver.test.d.ts.map +1 -0
- package/dist/theme/resolver.test.js +344 -0
- package/dist/theme/resolver.test.js.map +1 -0
- package/dist/theme/types.d.ts +378 -5
- package/dist/theme/types.d.ts.map +1 -1
- package/dist/types/config.d.ts +4 -4
- package/dist/types/index.d.ts +2 -2
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/uuid.d.ts.map +1 -1
- package/dist/utils/uuid.js +4 -5
- package/dist/utils/uuid.js.map +1 -1
- package/dist/utils/uuid.test.d.ts +2 -0
- package/dist/utils/uuid.test.d.ts.map +1 -0
- package/dist/utils/uuid.test.js +78 -0
- package/dist/utils/uuid.test.js.map +1 -0
- package/package.json +21 -13
- package/src/@types/expo-file-system-legacy.d.ts +3 -3
- package/src/__mocks__/async-storage.ts +46 -0
- package/src/__mocks__/expo-document-picker.ts +41 -0
- package/src/__mocks__/expo-file-system.ts +62 -0
- package/src/__mocks__/expo-image-picker.ts +48 -0
- package/src/__mocks__/expo-secure-store.ts +29 -0
- package/src/__mocks__/react-native.ts +46 -0
- package/src/api/client.test.ts +515 -0
- package/src/api/client.ts +45 -64
- package/src/api/errors.test.ts +193 -0
- package/src/api/errors.ts +7 -11
- package/src/api/index.ts +6 -10
- package/src/api/retry.test.ts +251 -0
- package/src/api/retry.ts +3 -6
- package/src/attachments/FeedbackSheet.tsx +100 -80
- package/src/attachments/index.ts +2 -2
- package/src/components/AttachmentGrid.tsx +54 -45
- package/src/components/AttachmentPicker.tsx +43 -54
- package/src/components/AttachmentPreview.tsx +51 -47
- package/src/components/CategorySelector.tsx +29 -35
- package/src/components/FeedbackForm.tsx +23 -35
- package/src/components/FeedbackSheet.tsx +89 -68
- package/src/components/ThemedButton.tsx +49 -47
- package/src/components/ThemedText.tsx +7 -10
- package/src/components/ThemedTextInput.tsx +23 -13
- package/src/components/UploadStatusOverlay.tsx +66 -89
- package/src/components/index.ts +18 -21
- package/src/context/HarkenContext.tsx +29 -28
- package/src/context/index.ts +2 -2
- package/src/domain/index.ts +2 -5
- package/src/domain/upload-queue.ts +5 -5
- package/src/hooks/index.ts +5 -5
- package/src/hooks/useAnonymousId.test.ts +189 -0
- package/src/hooks/useAnonymousId.ts +3 -3
- package/src/hooks/useAttachmentPicker.ts +12 -12
- package/src/hooks/useAttachmentStatus.ts +12 -16
- package/src/hooks/useAttachmentUpload.test.ts +632 -0
- package/src/hooks/useAttachmentUpload.ts +45 -54
- package/src/hooks/useFeedback.test.ts +376 -0
- package/src/hooks/useFeedback.ts +12 -14
- package/src/hooks/useHarkenContext.ts +4 -4
- package/src/hooks/useHarkenTheme.ts +30 -6
- package/src/index.ts +28 -52
- package/src/services/index.ts +3 -9
- package/src/services/uploadQueueService.test.ts +489 -0
- package/src/services/uploadQueueService.ts +40 -56
- package/src/services/uploadQueueStorage.test.ts +243 -0
- package/src/services/uploadQueueStorage.ts +7 -9
- package/src/storage/IdentityStore.test.ts +173 -0
- package/src/storage/IdentityStore.ts +4 -5
- package/src/storage/SecureStoreAdapter.test.ts +147 -0
- package/src/storage/SecureStoreAdapter.ts +1 -1
- package/src/storage/defaultStorage.test.ts +159 -0
- package/src/storage/defaultStorage.ts +6 -6
- package/src/storage/index.ts +5 -5
- package/src/storage/types.ts +1 -1
- package/src/theme/defaults.ts +75 -46
- package/src/theme/index.ts +15 -2
- package/src/theme/resolver.test.ts +411 -0
- package/src/theme/resolver.ts +446 -0
- package/src/theme/types.ts +453 -15
- package/src/types/config.ts +4 -4
- package/src/types/index.ts +2 -2
- package/src/utils/index.ts +1 -1
- package/src/utils/uuid.test.ts +85 -0
- package/src/utils/uuid.ts +4 -7
package/src/theme/types.ts
CHANGED
|
@@ -1,15 +1,21 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Color tokens for Harken SDK theming.
|
|
3
3
|
* All colors support full override by host apps.
|
|
4
|
+
*
|
|
5
|
+
* Base tokens are required. Component tokens are optional and fall back to base tokens.
|
|
4
6
|
*/
|
|
5
7
|
export interface HarkenColors {
|
|
8
|
+
// === BASE TOKENS (required) ===
|
|
9
|
+
|
|
6
10
|
/** Primary brand color for buttons and accents */
|
|
7
11
|
primary: string;
|
|
8
12
|
/** Darker variant of primary for pressed states */
|
|
9
13
|
primaryPressed: string;
|
|
10
|
-
/**
|
|
14
|
+
/** App-level background color */
|
|
11
15
|
background: string;
|
|
12
|
-
/**
|
|
16
|
+
/** Container/modal surface color (distinct from background) */
|
|
17
|
+
surface: string;
|
|
18
|
+
/** @deprecated Use `surface` instead. Kept for backwards compatibility. */
|
|
13
19
|
backgroundSecondary: string;
|
|
14
20
|
/** Primary text color */
|
|
15
21
|
text: string;
|
|
@@ -41,6 +47,106 @@ export interface HarkenColors {
|
|
|
41
47
|
accent2: string;
|
|
42
48
|
/** Accent color 3 (e.g., files option) */
|
|
43
49
|
accent3: string;
|
|
50
|
+
|
|
51
|
+
// === COMPONENT TOKENS (optional, fall back to base tokens) ===
|
|
52
|
+
|
|
53
|
+
// Category Chips
|
|
54
|
+
/** Chip background color (falls back to surface) */
|
|
55
|
+
chipBackground?: string;
|
|
56
|
+
/** Selected chip background color (falls back to primary) */
|
|
57
|
+
chipBackgroundSelected?: string;
|
|
58
|
+
/** Chip border color (falls back to border) */
|
|
59
|
+
chipBorder?: string;
|
|
60
|
+
/** Selected chip border color (falls back to primary) */
|
|
61
|
+
chipBorderSelected?: string;
|
|
62
|
+
/** Chip text color (falls back to text) */
|
|
63
|
+
chipText?: string;
|
|
64
|
+
/** Selected chip text color (falls back to textOnPrimary) */
|
|
65
|
+
chipTextSelected?: string;
|
|
66
|
+
|
|
67
|
+
// Text Input
|
|
68
|
+
/** Input background color (falls back to surface) */
|
|
69
|
+
inputBackground?: string;
|
|
70
|
+
/** Input border color (falls back to border) */
|
|
71
|
+
inputBorder?: string;
|
|
72
|
+
/** Input focused border color (falls back to borderFocused) */
|
|
73
|
+
inputBorderFocused?: string;
|
|
74
|
+
/** Input error border color (falls back to error) */
|
|
75
|
+
inputBorderError?: string;
|
|
76
|
+
/** Input text color (falls back to text) */
|
|
77
|
+
inputText?: string;
|
|
78
|
+
/** Input placeholder color (falls back to textPlaceholder) */
|
|
79
|
+
inputPlaceholder?: string;
|
|
80
|
+
|
|
81
|
+
// Buttons - Primary variant
|
|
82
|
+
/** Primary button background (falls back to primary) */
|
|
83
|
+
buttonPrimaryBackground?: string;
|
|
84
|
+
/** Primary button pressed background (falls back to primaryPressed) */
|
|
85
|
+
buttonPrimaryBackgroundPressed?: string;
|
|
86
|
+
/** Primary button text color (falls back to textOnPrimary) */
|
|
87
|
+
buttonPrimaryText?: string;
|
|
88
|
+
|
|
89
|
+
// Buttons - Secondary variant
|
|
90
|
+
/** Secondary button background (falls back to surface) */
|
|
91
|
+
buttonSecondaryBackground?: string;
|
|
92
|
+
/** Secondary button border color (falls back to border) */
|
|
93
|
+
buttonSecondaryBorder?: string;
|
|
94
|
+
/** Secondary button text color (falls back to text) */
|
|
95
|
+
buttonSecondaryText?: string;
|
|
96
|
+
|
|
97
|
+
// Buttons - Ghost variant
|
|
98
|
+
/** Ghost button text color (falls back to text) */
|
|
99
|
+
buttonGhostText?: string;
|
|
100
|
+
|
|
101
|
+
// Attachment Add Button
|
|
102
|
+
/** Add button background (falls back to surface) */
|
|
103
|
+
addButtonBackground?: string;
|
|
104
|
+
/** Add button pressed background (falls back to border) */
|
|
105
|
+
addButtonBackgroundPressed?: string;
|
|
106
|
+
/** Add button border color (falls back to border) */
|
|
107
|
+
addButtonBorder?: string;
|
|
108
|
+
/** Add button icon color (falls back to textSecondary) */
|
|
109
|
+
addButtonIcon?: string;
|
|
110
|
+
/** Add button text color (falls back to textSecondary) */
|
|
111
|
+
addButtonText?: string;
|
|
112
|
+
|
|
113
|
+
// Attachment Tile
|
|
114
|
+
/** Tile background color (falls back to surface) */
|
|
115
|
+
tileBackground?: string;
|
|
116
|
+
/** Tile border color (falls back to border) */
|
|
117
|
+
tileBorder?: string;
|
|
118
|
+
|
|
119
|
+
// Upload Status Overlay
|
|
120
|
+
/** Upload overlay background (falls back to overlay) */
|
|
121
|
+
uploadOverlay?: string;
|
|
122
|
+
/** Upload error overlay background (falls back to overlayDark) */
|
|
123
|
+
uploadOverlayError?: string;
|
|
124
|
+
/** Upload progress track color */
|
|
125
|
+
uploadProgressTrack?: string;
|
|
126
|
+
/** Upload progress fill color (falls back to primary) */
|
|
127
|
+
uploadProgressFill?: string;
|
|
128
|
+
/** Upload success badge color (falls back to success) */
|
|
129
|
+
uploadBadgeSuccess?: string;
|
|
130
|
+
/** Upload overlay text color (falls back to textOnPrimary) */
|
|
131
|
+
uploadText?: string;
|
|
132
|
+
|
|
133
|
+
// Attachment Picker
|
|
134
|
+
/** Picker overlay background (falls back to overlay) */
|
|
135
|
+
pickerOverlay?: string;
|
|
136
|
+
/** Picker sheet background (falls back to background) */
|
|
137
|
+
pickerBackground?: string;
|
|
138
|
+
/** Picker handle color (falls back to textSecondary) */
|
|
139
|
+
pickerHandle?: string;
|
|
140
|
+
/** Picker option background (falls back to surface) */
|
|
141
|
+
pickerOptionBackground?: string;
|
|
142
|
+
/** Picker option pressed background (falls back to border) */
|
|
143
|
+
pickerOptionBackgroundPressed?: string;
|
|
144
|
+
/** Picker cancel text color (falls back to error) */
|
|
145
|
+
pickerCancelText?: string;
|
|
146
|
+
|
|
147
|
+
// Form Container
|
|
148
|
+
/** Form background color (falls back to transparent for modal embedding) */
|
|
149
|
+
formBackground?: string;
|
|
44
150
|
}
|
|
45
151
|
|
|
46
152
|
/**
|
|
@@ -80,23 +186,27 @@ export interface HarkenTypography {
|
|
|
80
186
|
|
|
81
187
|
/** Font weight values supported across platforms */
|
|
82
188
|
export type TextWeight =
|
|
83
|
-
|
|
|
84
|
-
|
|
|
85
|
-
|
|
|
86
|
-
|
|
|
87
|
-
|
|
|
88
|
-
|
|
|
89
|
-
|
|
|
90
|
-
|
|
|
91
|
-
|
|
|
92
|
-
|
|
|
93
|
-
|
|
|
189
|
+
| "normal"
|
|
190
|
+
| "bold"
|
|
191
|
+
| "100"
|
|
192
|
+
| "200"
|
|
193
|
+
| "300"
|
|
194
|
+
| "400"
|
|
195
|
+
| "500"
|
|
196
|
+
| "600"
|
|
197
|
+
| "700"
|
|
198
|
+
| "800"
|
|
199
|
+
| "900";
|
|
94
200
|
|
|
95
201
|
/**
|
|
96
202
|
* Spacing tokens for consistent layout.
|
|
97
203
|
* All values are in logical pixels.
|
|
204
|
+
*
|
|
205
|
+
* Base tokens are required. Component tokens are optional and fall back to base tokens.
|
|
98
206
|
*/
|
|
99
207
|
export interface HarkenSpacing {
|
|
208
|
+
// === BASE TOKENS (required) ===
|
|
209
|
+
|
|
100
210
|
/** Extra small spacing (4px default) */
|
|
101
211
|
xs: number;
|
|
102
212
|
/** Small spacing (8px default) */
|
|
@@ -109,13 +219,38 @@ export interface HarkenSpacing {
|
|
|
109
219
|
xl: number;
|
|
110
220
|
/** 2x extra large spacing (48px default) */
|
|
111
221
|
xxl: number;
|
|
222
|
+
|
|
223
|
+
// === COMPONENT TOKENS (optional, fall back to base tokens) ===
|
|
224
|
+
|
|
225
|
+
/** Chip vertical padding (falls back to sm) */
|
|
226
|
+
chipPaddingVertical?: number;
|
|
227
|
+
/** Chip horizontal padding (falls back to md) */
|
|
228
|
+
chipPaddingHorizontal?: number;
|
|
229
|
+
/** Gap between chips (falls back to sm) */
|
|
230
|
+
chipGap?: number;
|
|
231
|
+
/** Input padding (falls back to md) */
|
|
232
|
+
inputPadding?: number;
|
|
233
|
+
/** Button vertical padding (falls back to sm) */
|
|
234
|
+
buttonPaddingVertical?: number;
|
|
235
|
+
/** Button horizontal padding (falls back to md) */
|
|
236
|
+
buttonPaddingHorizontal?: number;
|
|
237
|
+
/** Form container padding (falls back to lg) */
|
|
238
|
+
formPadding?: number;
|
|
239
|
+
/** Gap between form sections (falls back to lg) */
|
|
240
|
+
sectionGap?: number;
|
|
241
|
+
/** Gap between attachment tiles (falls back to sm) */
|
|
242
|
+
tileGap?: number;
|
|
112
243
|
}
|
|
113
244
|
|
|
114
245
|
/**
|
|
115
246
|
* Border radius tokens for rounded corners.
|
|
116
247
|
* All values are in logical pixels.
|
|
248
|
+
*
|
|
249
|
+
* Base tokens are required. Component tokens are optional and fall back to base tokens.
|
|
117
250
|
*/
|
|
118
251
|
export interface HarkenRadii {
|
|
252
|
+
// === BASE TOKENS (required) ===
|
|
253
|
+
|
|
119
254
|
/** No radius */
|
|
120
255
|
none: number;
|
|
121
256
|
/** Small radius for subtle rounding (4px default) */
|
|
@@ -128,16 +263,62 @@ export interface HarkenRadii {
|
|
|
128
263
|
xl: number;
|
|
129
264
|
/** Full/pill radius */
|
|
130
265
|
full: number;
|
|
266
|
+
|
|
267
|
+
// === COMPONENT TOKENS (optional, fall back to base tokens) ===
|
|
268
|
+
|
|
269
|
+
/** Chip border radius (falls back to full) */
|
|
270
|
+
chip?: number;
|
|
271
|
+
/** Input border radius (falls back to md) */
|
|
272
|
+
input?: number;
|
|
273
|
+
/** Button border radius (falls back to md) */
|
|
274
|
+
button?: number;
|
|
275
|
+
/** Attachment tile border radius (falls back to md) */
|
|
276
|
+
tile?: number;
|
|
277
|
+
/** Form container border radius (falls back to lg) */
|
|
278
|
+
form?: number;
|
|
279
|
+
/** Picker sheet border radius (falls back to xl) */
|
|
280
|
+
picker?: number;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* Sizing tokens for component dimensions.
|
|
285
|
+
* All values are in logical pixels and optional with sensible defaults.
|
|
286
|
+
*/
|
|
287
|
+
export interface HarkenSizing {
|
|
288
|
+
/** Button minimum height (default: 48) */
|
|
289
|
+
buttonMinHeight?: number;
|
|
290
|
+
/** Input minimum height (default: 44) */
|
|
291
|
+
inputMinHeight?: number;
|
|
292
|
+
/** Attachment tile size (default: 80) */
|
|
293
|
+
tileSize?: number;
|
|
294
|
+
/** Add button icon size (default: 28) */
|
|
295
|
+
addButtonIconSize?: number;
|
|
296
|
+
/** Picker icon container size (default: 44) */
|
|
297
|
+
pickerIconSize?: number;
|
|
131
298
|
}
|
|
132
299
|
|
|
133
300
|
/**
|
|
134
|
-
*
|
|
301
|
+
* Opacity tokens for interactive states.
|
|
302
|
+
* All values are between 0 and 1 and optional with sensible defaults.
|
|
303
|
+
*/
|
|
304
|
+
export interface HarkenOpacity {
|
|
305
|
+
/** Disabled state opacity (default: 0.6) */
|
|
306
|
+
disabled?: number;
|
|
307
|
+
/** Pressed state opacity (default: 0.8) */
|
|
308
|
+
pressed?: number;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
/**
|
|
312
|
+
* Input theme object with optional component tokens.
|
|
313
|
+
* Used for theme configuration by consumers.
|
|
135
314
|
*/
|
|
136
315
|
export interface HarkenTheme {
|
|
137
316
|
colors: HarkenColors;
|
|
138
317
|
typography: HarkenTypography;
|
|
139
318
|
spacing: HarkenSpacing;
|
|
140
319
|
radii: HarkenRadii;
|
|
320
|
+
sizing?: HarkenSizing;
|
|
321
|
+
opacity?: HarkenOpacity;
|
|
141
322
|
}
|
|
142
323
|
|
|
143
324
|
/**
|
|
@@ -149,9 +330,266 @@ export type PartialHarkenTheme = {
|
|
|
149
330
|
typography?: Partial<HarkenTypography>;
|
|
150
331
|
spacing?: Partial<HarkenSpacing>;
|
|
151
332
|
radii?: Partial<HarkenRadii>;
|
|
333
|
+
sizing?: Partial<HarkenSizing>;
|
|
334
|
+
opacity?: Partial<HarkenOpacity>;
|
|
152
335
|
};
|
|
153
336
|
|
|
154
337
|
/**
|
|
155
338
|
* Theme mode for automatic light/dark theming.
|
|
156
339
|
*/
|
|
157
|
-
export type ThemeMode =
|
|
340
|
+
export type ThemeMode = "light" | "dark" | "system";
|
|
341
|
+
|
|
342
|
+
// ============================================================================
|
|
343
|
+
// RESOLVED THEME TYPES
|
|
344
|
+
// These types represent the fully-resolved theme after fallback resolution.
|
|
345
|
+
// Components should use these types - all values are guaranteed to exist.
|
|
346
|
+
// ============================================================================
|
|
347
|
+
|
|
348
|
+
/**
|
|
349
|
+
* Fully resolved color tokens with all component tokens populated.
|
|
350
|
+
* All optional component tokens have been resolved to their fallback values.
|
|
351
|
+
*/
|
|
352
|
+
export interface ResolvedHarkenColors {
|
|
353
|
+
// Base tokens
|
|
354
|
+
primary: string;
|
|
355
|
+
primaryPressed: string;
|
|
356
|
+
background: string;
|
|
357
|
+
surface: string;
|
|
358
|
+
backgroundSecondary: string;
|
|
359
|
+
text: string;
|
|
360
|
+
textSecondary: string;
|
|
361
|
+
textPlaceholder: string;
|
|
362
|
+
textOnPrimary: string;
|
|
363
|
+
border: string;
|
|
364
|
+
borderFocused: string;
|
|
365
|
+
error: string;
|
|
366
|
+
success: string;
|
|
367
|
+
warning: string;
|
|
368
|
+
info: string;
|
|
369
|
+
overlay: string;
|
|
370
|
+
overlayDark: string;
|
|
371
|
+
accent1: string;
|
|
372
|
+
accent2: string;
|
|
373
|
+
accent3: string;
|
|
374
|
+
|
|
375
|
+
// Component tokens (all resolved, no longer optional)
|
|
376
|
+
chipBackground: string;
|
|
377
|
+
chipBackgroundSelected: string;
|
|
378
|
+
chipBorder: string;
|
|
379
|
+
chipBorderSelected: string;
|
|
380
|
+
chipText: string;
|
|
381
|
+
chipTextSelected: string;
|
|
382
|
+
|
|
383
|
+
inputBackground: string;
|
|
384
|
+
inputBorder: string;
|
|
385
|
+
inputBorderFocused: string;
|
|
386
|
+
inputBorderError: string;
|
|
387
|
+
inputText: string;
|
|
388
|
+
inputPlaceholder: string;
|
|
389
|
+
|
|
390
|
+
buttonPrimaryBackground: string;
|
|
391
|
+
buttonPrimaryBackgroundPressed: string;
|
|
392
|
+
buttonPrimaryText: string;
|
|
393
|
+
buttonSecondaryBackground: string;
|
|
394
|
+
buttonSecondaryBorder: string;
|
|
395
|
+
buttonSecondaryText: string;
|
|
396
|
+
buttonGhostText: string;
|
|
397
|
+
|
|
398
|
+
addButtonBackground: string;
|
|
399
|
+
addButtonBackgroundPressed: string;
|
|
400
|
+
addButtonBorder: string;
|
|
401
|
+
addButtonIcon: string;
|
|
402
|
+
addButtonText: string;
|
|
403
|
+
|
|
404
|
+
tileBackground: string;
|
|
405
|
+
tileBorder: string;
|
|
406
|
+
|
|
407
|
+
uploadOverlay: string;
|
|
408
|
+
uploadOverlayError: string;
|
|
409
|
+
uploadProgressTrack: string;
|
|
410
|
+
uploadProgressFill: string;
|
|
411
|
+
uploadBadgeSuccess: string;
|
|
412
|
+
uploadText: string;
|
|
413
|
+
|
|
414
|
+
pickerOverlay: string;
|
|
415
|
+
pickerBackground: string;
|
|
416
|
+
pickerHandle: string;
|
|
417
|
+
pickerOptionBackground: string;
|
|
418
|
+
pickerOptionBackgroundPressed: string;
|
|
419
|
+
pickerCancelText: string;
|
|
420
|
+
|
|
421
|
+
formBackground: string;
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
/**
|
|
425
|
+
* Fully resolved spacing tokens with all component tokens populated.
|
|
426
|
+
*/
|
|
427
|
+
export interface ResolvedHarkenSpacing {
|
|
428
|
+
// Base tokens
|
|
429
|
+
xs: number;
|
|
430
|
+
sm: number;
|
|
431
|
+
md: number;
|
|
432
|
+
lg: number;
|
|
433
|
+
xl: number;
|
|
434
|
+
xxl: number;
|
|
435
|
+
|
|
436
|
+
// Component tokens (all resolved)
|
|
437
|
+
chipPaddingVertical: number;
|
|
438
|
+
chipPaddingHorizontal: number;
|
|
439
|
+
chipGap: number;
|
|
440
|
+
inputPadding: number;
|
|
441
|
+
buttonPaddingVertical: number;
|
|
442
|
+
buttonPaddingHorizontal: number;
|
|
443
|
+
formPadding: number;
|
|
444
|
+
sectionGap: number;
|
|
445
|
+
tileGap: number;
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
/**
|
|
449
|
+
* Fully resolved radii tokens with all component tokens populated.
|
|
450
|
+
*/
|
|
451
|
+
export interface ResolvedHarkenRadii {
|
|
452
|
+
// Base tokens
|
|
453
|
+
none: number;
|
|
454
|
+
sm: number;
|
|
455
|
+
md: number;
|
|
456
|
+
lg: number;
|
|
457
|
+
xl: number;
|
|
458
|
+
full: number;
|
|
459
|
+
|
|
460
|
+
// Component tokens (all resolved)
|
|
461
|
+
chip: number;
|
|
462
|
+
input: number;
|
|
463
|
+
button: number;
|
|
464
|
+
tile: number;
|
|
465
|
+
form: number;
|
|
466
|
+
picker: number;
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
/**
|
|
470
|
+
* Fully resolved sizing tokens.
|
|
471
|
+
*/
|
|
472
|
+
export interface ResolvedHarkenSizing {
|
|
473
|
+
buttonMinHeight: number;
|
|
474
|
+
inputMinHeight: number;
|
|
475
|
+
tileSize: number;
|
|
476
|
+
addButtonIconSize: number;
|
|
477
|
+
pickerIconSize: number;
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
/**
|
|
481
|
+
* Fully resolved opacity tokens.
|
|
482
|
+
*/
|
|
483
|
+
export interface ResolvedHarkenOpacity {
|
|
484
|
+
disabled: number;
|
|
485
|
+
pressed: number;
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
/**
|
|
489
|
+
* Structured component token aliases for better discoverability.
|
|
490
|
+
* Maps to flat tokens but grouped by component for ergonomic access.
|
|
491
|
+
*/
|
|
492
|
+
export interface HarkenComponentTokens {
|
|
493
|
+
chip: {
|
|
494
|
+
background: string;
|
|
495
|
+
backgroundSelected: string;
|
|
496
|
+
border: string;
|
|
497
|
+
borderSelected: string;
|
|
498
|
+
text: string;
|
|
499
|
+
textSelected: string;
|
|
500
|
+
paddingVertical: number;
|
|
501
|
+
paddingHorizontal: number;
|
|
502
|
+
gap: number;
|
|
503
|
+
radius: number;
|
|
504
|
+
};
|
|
505
|
+
input: {
|
|
506
|
+
background: string;
|
|
507
|
+
border: string;
|
|
508
|
+
borderFocused: string;
|
|
509
|
+
borderError: string;
|
|
510
|
+
text: string;
|
|
511
|
+
placeholder: string;
|
|
512
|
+
padding: number;
|
|
513
|
+
radius: number;
|
|
514
|
+
minHeight: number;
|
|
515
|
+
};
|
|
516
|
+
button: {
|
|
517
|
+
primary: {
|
|
518
|
+
background: string;
|
|
519
|
+
backgroundPressed: string;
|
|
520
|
+
text: string;
|
|
521
|
+
};
|
|
522
|
+
secondary: {
|
|
523
|
+
background: string;
|
|
524
|
+
border: string;
|
|
525
|
+
text: string;
|
|
526
|
+
};
|
|
527
|
+
ghost: {
|
|
528
|
+
text: string;
|
|
529
|
+
};
|
|
530
|
+
paddingVertical: number;
|
|
531
|
+
paddingHorizontal: number;
|
|
532
|
+
radius: number;
|
|
533
|
+
minHeight: number;
|
|
534
|
+
};
|
|
535
|
+
addButton: {
|
|
536
|
+
background: string;
|
|
537
|
+
backgroundPressed: string;
|
|
538
|
+
border: string;
|
|
539
|
+
icon: string;
|
|
540
|
+
text: string;
|
|
541
|
+
iconSize: number;
|
|
542
|
+
};
|
|
543
|
+
tile: {
|
|
544
|
+
background: string;
|
|
545
|
+
border: string;
|
|
546
|
+
radius: number;
|
|
547
|
+
size: number;
|
|
548
|
+
gap: number;
|
|
549
|
+
};
|
|
550
|
+
upload: {
|
|
551
|
+
overlay: string;
|
|
552
|
+
overlayError: string;
|
|
553
|
+
progressTrack: string;
|
|
554
|
+
progressFill: string;
|
|
555
|
+
badgeSuccess: string;
|
|
556
|
+
text: string;
|
|
557
|
+
};
|
|
558
|
+
picker: {
|
|
559
|
+
overlay: string;
|
|
560
|
+
background: string;
|
|
561
|
+
handle: string;
|
|
562
|
+
optionBackground: string;
|
|
563
|
+
optionBackgroundPressed: string;
|
|
564
|
+
cancelText: string;
|
|
565
|
+
radius: number;
|
|
566
|
+
iconSize: number;
|
|
567
|
+
};
|
|
568
|
+
form: {
|
|
569
|
+
background: string;
|
|
570
|
+
padding: number;
|
|
571
|
+
sectionGap: number;
|
|
572
|
+
radius: number;
|
|
573
|
+
};
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
/**
|
|
577
|
+
* Fully resolved theme object with all fallbacks applied.
|
|
578
|
+
* This is what components receive - all values are guaranteed to exist.
|
|
579
|
+
*/
|
|
580
|
+
export interface ResolvedHarkenTheme {
|
|
581
|
+
/** Flat color tokens (for compatibility) */
|
|
582
|
+
colors: ResolvedHarkenColors;
|
|
583
|
+
/** Typography tokens */
|
|
584
|
+
typography: HarkenTypography;
|
|
585
|
+
/** Flat spacing tokens (for compatibility) */
|
|
586
|
+
spacing: ResolvedHarkenSpacing;
|
|
587
|
+
/** Flat radii tokens (for compatibility) */
|
|
588
|
+
radii: ResolvedHarkenRadii;
|
|
589
|
+
/** Sizing tokens */
|
|
590
|
+
sizing: ResolvedHarkenSizing;
|
|
591
|
+
/** Opacity tokens */
|
|
592
|
+
opacity: ResolvedHarkenOpacity;
|
|
593
|
+
/** Structured component tokens (for discoverability) */
|
|
594
|
+
components: HarkenComponentTokens;
|
|
595
|
+
}
|
package/src/types/config.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { PartialHarkenTheme, ThemeMode } from
|
|
2
|
-
import type { SecureStorage } from
|
|
1
|
+
import type { PartialHarkenTheme, ThemeMode } from "../theme";
|
|
2
|
+
import type { SecureStorage } from "../storage";
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Configuration options for the Harken SDK.
|
|
@@ -88,12 +88,12 @@ export interface HarkenProviderProps {
|
|
|
88
88
|
/**
|
|
89
89
|
* Feedback category types supported by the API.
|
|
90
90
|
*/
|
|
91
|
-
export type FeedbackCategory =
|
|
91
|
+
export type FeedbackCategory = "bug" | "idea" | "ux" | "other";
|
|
92
92
|
|
|
93
93
|
/**
|
|
94
94
|
* Platform type for device metadata.
|
|
95
95
|
*/
|
|
96
|
-
export type Platform =
|
|
96
|
+
export type Platform = "ios" | "android";
|
|
97
97
|
|
|
98
98
|
/**
|
|
99
99
|
* Device metadata collected with feedback submissions.
|
package/src/types/index.ts
CHANGED
|
@@ -4,7 +4,7 @@ export type {
|
|
|
4
4
|
FeedbackCategory,
|
|
5
5
|
Platform,
|
|
6
6
|
DeviceMetadata,
|
|
7
|
-
} from
|
|
7
|
+
} from "./config.js";
|
|
8
8
|
|
|
9
9
|
// Re-export OpenAPI generated types
|
|
10
|
-
export type { components, operations, paths } from
|
|
10
|
+
export type { components, operations, paths } from "./openapi.js";
|
package/src/utils/index.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { generateUUID } from
|
|
1
|
+
export { generateUUID } from "./uuid";
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { generateUUID } from "./uuid";
|
|
3
|
+
|
|
4
|
+
describe("generateUUID", () => {
|
|
5
|
+
// UUID v4 format: xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx
|
|
6
|
+
// where y is one of [8, 9, a, b]
|
|
7
|
+
const uuidV4Regex = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
8
|
+
|
|
9
|
+
it("generates valid UUID v4 format", () => {
|
|
10
|
+
const uuid = generateUUID();
|
|
11
|
+
expect(uuid).toMatch(uuidV4Regex);
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
it("generates 36-character string with hyphens", () => {
|
|
15
|
+
const uuid = generateUUID();
|
|
16
|
+
expect(uuid).toHaveLength(36);
|
|
17
|
+
expect(uuid.split("-")).toHaveLength(5);
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it("has version 4 identifier in correct position", () => {
|
|
21
|
+
const uuid = generateUUID();
|
|
22
|
+
// The 13th character (index 14, after first two groups) should be '4'
|
|
23
|
+
expect(uuid[14]).toBe("4");
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it("has valid variant bits", () => {
|
|
27
|
+
const uuid = generateUUID();
|
|
28
|
+
// The 17th character (index 19, after third group) should be 8, 9, a, or b
|
|
29
|
+
expect(["8", "9", "a", "b"]).toContain(uuid[19]!.toLowerCase());
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it("uses lowercase hex characters", () => {
|
|
33
|
+
// Generate multiple to ensure consistent format
|
|
34
|
+
for (let i = 0; i < 10; i++) {
|
|
35
|
+
const uuid = generateUUID();
|
|
36
|
+
const hexPart = uuid.replace(/-/g, "");
|
|
37
|
+
expect(hexPart).toMatch(/^[0-9a-f]+$/);
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
describe("with crypto.getRandomValues available", () => {
|
|
42
|
+
it("uses crypto for randomness", () => {
|
|
43
|
+
// crypto.getRandomValues is available in Node.js
|
|
44
|
+
const uuid = generateUUID();
|
|
45
|
+
expect(uuid).toMatch(uuidV4Regex);
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
describe("fallback with Math.random", () => {
|
|
50
|
+
// Note: We can't easily test the Math.random fallback in Node.js
|
|
51
|
+
// because crypto is a read-only property. The fallback path
|
|
52
|
+
// is tested implicitly by the fact that our implementation handles
|
|
53
|
+
// the case where crypto might not exist (React Native older runtimes).
|
|
54
|
+
//
|
|
55
|
+
// Instead, we verify the algorithm produces valid UUIDs with any
|
|
56
|
+
// randomness source by testing the format constraints.
|
|
57
|
+
|
|
58
|
+
it("algorithm produces valid version and variant bits", () => {
|
|
59
|
+
// The UUID generation algorithm sets version=4 and variant=RFC4122
|
|
60
|
+
// regardless of which random source is used. We verify this by
|
|
61
|
+
// generating many UUIDs and checking format compliance.
|
|
62
|
+
for (let i = 0; i < 100; i++) {
|
|
63
|
+
const uuid = generateUUID();
|
|
64
|
+
// Version 4 at position 14
|
|
65
|
+
expect(uuid[14]).toBe("4");
|
|
66
|
+
// Variant at position 19 is 8, 9, a, or b
|
|
67
|
+
expect(["8", "9", "a", "b"]).toContain(uuid[19]!.toLowerCase());
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
describe("format consistency", () => {
|
|
73
|
+
it("consistently produces 8-4-4-4-12 format", () => {
|
|
74
|
+
for (let i = 0; i < 10; i++) {
|
|
75
|
+
const uuid = generateUUID();
|
|
76
|
+
const parts = uuid.split("-");
|
|
77
|
+
expect(parts[0]).toHaveLength(8);
|
|
78
|
+
expect(parts[1]).toHaveLength(4);
|
|
79
|
+
expect(parts[2]).toHaveLength(4);
|
|
80
|
+
expect(parts[3]).toHaveLength(4);
|
|
81
|
+
expect(parts[4]).toHaveLength(12);
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
});
|
package/src/utils/uuid.ts
CHANGED
|
@@ -18,10 +18,7 @@ declare const crypto:
|
|
|
18
18
|
*/
|
|
19
19
|
export function generateUUID(): string {
|
|
20
20
|
// Use crypto.getRandomValues if available (React Native has this)
|
|
21
|
-
if (
|
|
22
|
-
typeof crypto !== 'undefined' &&
|
|
23
|
-
typeof crypto.getRandomValues === 'function'
|
|
24
|
-
) {
|
|
21
|
+
if (typeof crypto !== "undefined" && typeof crypto.getRandomValues === "function") {
|
|
25
22
|
return generateUUIDCrypto();
|
|
26
23
|
}
|
|
27
24
|
|
|
@@ -64,8 +61,8 @@ function generateUUIDFallback(): string {
|
|
|
64
61
|
*/
|
|
65
62
|
function formatUUID(bytes: Uint8Array): string {
|
|
66
63
|
const hex = Array.from(bytes)
|
|
67
|
-
.map((b) => b.toString(16).padStart(2,
|
|
68
|
-
.join(
|
|
64
|
+
.map((b) => b.toString(16).padStart(2, "0"))
|
|
65
|
+
.join("");
|
|
69
66
|
|
|
70
67
|
return [
|
|
71
68
|
hex.slice(0, 8),
|
|
@@ -73,5 +70,5 @@ function formatUUID(bytes: Uint8Array): string {
|
|
|
73
70
|
hex.slice(12, 16),
|
|
74
71
|
hex.slice(16, 20),
|
|
75
72
|
hex.slice(20, 32),
|
|
76
|
-
].join(
|
|
73
|
+
].join("-");
|
|
77
74
|
}
|