@entropy-softworks/ui 2026.7.31
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/CHANGELOG.md +96 -0
- package/LICENSE +21 -0
- package/README.md +115 -0
- package/lib/components/auth/LockOverlay.d.ts +22 -0
- package/lib/components/auth/LockOverlay.d.ts.map +1 -0
- package/lib/components/auth/LockOverlay.jsx +82 -0
- package/lib/components/auth/LockOverlay.jsx.map +1 -0
- package/lib/components/auth/PasswordStrengthMeter.d.ts +12 -0
- package/lib/components/auth/PasswordStrengthMeter.d.ts.map +1 -0
- package/lib/components/auth/PasswordStrengthMeter.jsx +81 -0
- package/lib/components/auth/PasswordStrengthMeter.jsx.map +1 -0
- package/lib/components/auth/ProtectedRoute.d.ts +24 -0
- package/lib/components/auth/ProtectedRoute.d.ts.map +1 -0
- package/lib/components/auth/ProtectedRoute.jsx +56 -0
- package/lib/components/auth/ProtectedRoute.jsx.map +1 -0
- package/lib/components/auth/PwnedPasswordWarning.d.ts +13 -0
- package/lib/components/auth/PwnedPasswordWarning.d.ts.map +1 -0
- package/lib/components/auth/PwnedPasswordWarning.jsx +29 -0
- package/lib/components/auth/PwnedPasswordWarning.jsx.map +1 -0
- package/lib/components/auth/index.d.ts +5 -0
- package/lib/components/auth/index.d.ts.map +1 -0
- package/lib/components/auth/index.js +5 -0
- package/lib/components/auth/index.js.map +1 -0
- package/lib/components/bottom-nav.d.ts +25 -0
- package/lib/components/bottom-nav.d.ts.map +1 -0
- package/lib/components/bottom-nav.jsx +51 -0
- package/lib/components/bottom-nav.jsx.map +1 -0
- package/lib/components/button.d.ts +16 -0
- package/lib/components/button.d.ts.map +1 -0
- package/lib/components/button.jsx +73 -0
- package/lib/components/button.jsx.map +1 -0
- package/lib/components/card.d.ts +22 -0
- package/lib/components/card.d.ts.map +1 -0
- package/lib/components/card.jsx +36 -0
- package/lib/components/card.jsx.map +1 -0
- package/lib/components/checkbox.d.ts +12 -0
- package/lib/components/checkbox.d.ts.map +1 -0
- package/lib/components/checkbox.jsx +16 -0
- package/lib/components/checkbox.jsx.map +1 -0
- package/lib/components/connection-settings.d.ts +41 -0
- package/lib/components/connection-settings.d.ts.map +1 -0
- package/lib/components/connection-settings.jsx +354 -0
- package/lib/components/connection-settings.jsx.map +1 -0
- package/lib/components/context-menu.d.ts +52 -0
- package/lib/components/context-menu.d.ts.map +1 -0
- package/lib/components/context-menu.jsx +24 -0
- package/lib/components/context-menu.jsx.map +1 -0
- package/lib/components/data-table.d.ts +59 -0
- package/lib/components/data-table.d.ts.map +1 -0
- package/lib/components/data-table.jsx +101 -0
- package/lib/components/data-table.jsx.map +1 -0
- package/lib/components/dialog.d.ts +58 -0
- package/lib/components/dialog.d.ts.map +1 -0
- package/lib/components/dialog.jsx +197 -0
- package/lib/components/dialog.jsx.map +1 -0
- package/lib/components/dropdown-menu.d.ts +55 -0
- package/lib/components/dropdown-menu.d.ts.map +1 -0
- package/lib/components/dropdown-menu.jsx +38 -0
- package/lib/components/dropdown-menu.jsx.map +1 -0
- package/lib/components/entropy-boot-splash.d.ts +24 -0
- package/lib/components/entropy-boot-splash.d.ts.map +1 -0
- package/lib/components/entropy-boot-splash.jsx +83 -0
- package/lib/components/entropy-boot-splash.jsx.map +1 -0
- package/lib/components/entropy-mark-animated.d.ts +20 -0
- package/lib/components/entropy-mark-animated.d.ts.map +1 -0
- package/lib/components/entropy-mark-animated.jsx +148 -0
- package/lib/components/entropy-mark-animated.jsx.map +1 -0
- package/lib/components/entropy-mark-geometry.d.ts +8 -0
- package/lib/components/entropy-mark-geometry.d.ts.map +1 -0
- package/lib/components/entropy-mark-geometry.js +10 -0
- package/lib/components/entropy-mark-geometry.js.map +1 -0
- package/lib/components/entropy-mark-sequential.d.ts +12 -0
- package/lib/components/entropy-mark-sequential.d.ts.map +1 -0
- package/lib/components/entropy-mark-sequential.jsx +53 -0
- package/lib/components/entropy-mark-sequential.jsx.map +1 -0
- package/lib/components/entropy-mark.d.ts +29 -0
- package/lib/components/entropy-mark.d.ts.map +1 -0
- package/lib/components/entropy-mark.jsx +66 -0
- package/lib/components/entropy-mark.jsx.map +1 -0
- package/lib/components/error-boundary.d.ts +31 -0
- package/lib/components/error-boundary.d.ts.map +1 -0
- package/lib/components/error-boundary.jsx +40 -0
- package/lib/components/error-boundary.jsx.map +1 -0
- package/lib/components/index.d.ts +41 -0
- package/lib/components/index.d.ts.map +1 -0
- package/lib/components/index.js +43 -0
- package/lib/components/index.js.map +1 -0
- package/lib/components/input.d.ts +26 -0
- package/lib/components/input.d.ts.map +1 -0
- package/lib/components/input.jsx +95 -0
- package/lib/components/input.jsx.map +1 -0
- package/lib/components/item-icon.d.ts +32 -0
- package/lib/components/item-icon.d.ts.map +1 -0
- package/lib/components/item-icon.jsx +54 -0
- package/lib/components/item-icon.jsx.map +1 -0
- package/lib/components/label.d.ts +13 -0
- package/lib/components/label.d.ts.map +1 -0
- package/lib/components/label.jsx +9 -0
- package/lib/components/label.jsx.map +1 -0
- package/lib/components/legal-dialog.d.ts +18 -0
- package/lib/components/legal-dialog.d.ts.map +1 -0
- package/lib/components/legal-dialog.jsx +31 -0
- package/lib/components/legal-dialog.jsx.map +1 -0
- package/lib/components/license-gate.d.ts +17 -0
- package/lib/components/license-gate.d.ts.map +1 -0
- package/lib/components/license-gate.jsx +21 -0
- package/lib/components/license-gate.jsx.map +1 -0
- package/lib/components/logo.d.ts +15 -0
- package/lib/components/logo.d.ts.map +1 -0
- package/lib/components/logo.jsx +20 -0
- package/lib/components/logo.jsx.map +1 -0
- package/lib/components/onboarding-wizard.d.ts +89 -0
- package/lib/components/onboarding-wizard.d.ts.map +1 -0
- package/lib/components/onboarding-wizard.jsx +185 -0
- package/lib/components/onboarding-wizard.jsx.map +1 -0
- package/lib/components/pagination.d.ts +43 -0
- package/lib/components/pagination.d.ts.map +1 -0
- package/lib/components/pagination.jsx +72 -0
- package/lib/components/pagination.jsx.map +1 -0
- package/lib/components/password-generator.d.ts +15 -0
- package/lib/components/password-generator.d.ts.map +1 -0
- package/lib/components/password-generator.jsx +273 -0
- package/lib/components/password-generator.jsx.map +1 -0
- package/lib/components/pin-pad.d.ts +20 -0
- package/lib/components/pin-pad.d.ts.map +1 -0
- package/lib/components/pin-pad.jsx +93 -0
- package/lib/components/pin-pad.jsx.map +1 -0
- package/lib/components/popover.d.ts +27 -0
- package/lib/components/popover.d.ts.map +1 -0
- package/lib/components/popover.jsx +18 -0
- package/lib/components/popover.jsx.map +1 -0
- package/lib/components/profile/ProfileDialog.d.ts +25 -0
- package/lib/components/profile/ProfileDialog.d.ts.map +1 -0
- package/lib/components/profile/ProfileDialog.jsx +71 -0
- package/lib/components/profile/ProfileDialog.jsx.map +1 -0
- package/lib/components/profile/ProfileTab.d.ts +12 -0
- package/lib/components/profile/ProfileTab.d.ts.map +1 -0
- package/lib/components/profile/ProfileTab.jsx +112 -0
- package/lib/components/profile/ProfileTab.jsx.map +1 -0
- package/lib/components/profile/SecurityTab.d.ts +32 -0
- package/lib/components/profile/SecurityTab.d.ts.map +1 -0
- package/lib/components/profile/SecurityTab.jsx +145 -0
- package/lib/components/profile/SecurityTab.jsx.map +1 -0
- package/lib/components/profile/index.d.ts +4 -0
- package/lib/components/profile/index.d.ts.map +1 -0
- package/lib/components/profile/index.js +4 -0
- package/lib/components/profile/index.js.map +1 -0
- package/lib/components/segmented-toggle.d.ts +28 -0
- package/lib/components/segmented-toggle.d.ts.map +1 -0
- package/lib/components/segmented-toggle.jsx +64 -0
- package/lib/components/segmented-toggle.jsx.map +1 -0
- package/lib/components/separator.d.ts +13 -0
- package/lib/components/separator.d.ts.map +1 -0
- package/lib/components/separator.jsx +16 -0
- package/lib/components/separator.jsx.map +1 -0
- package/lib/components/server-settings.d.ts +27 -0
- package/lib/components/server-settings.d.ts.map +1 -0
- package/lib/components/server-settings.jsx +307 -0
- package/lib/components/server-settings.jsx.map +1 -0
- package/lib/components/settings/AccountSection.d.ts +26 -0
- package/lib/components/settings/AccountSection.d.ts.map +1 -0
- package/lib/components/settings/AccountSection.jsx +32 -0
- package/lib/components/settings/AccountSection.jsx.map +1 -0
- package/lib/components/settings/DangerZoneSection.d.ts +13 -0
- package/lib/components/settings/DangerZoneSection.d.ts.map +1 -0
- package/lib/components/settings/DangerZoneSection.jsx +16 -0
- package/lib/components/settings/DangerZoneSection.jsx.map +1 -0
- package/lib/components/settings/GeneralSection.d.ts +11 -0
- package/lib/components/settings/GeneralSection.d.ts.map +1 -0
- package/lib/components/settings/GeneralSection.jsx +12 -0
- package/lib/components/settings/GeneralSection.jsx.map +1 -0
- package/lib/components/settings/SupportSection.d.ts +11 -0
- package/lib/components/settings/SupportSection.d.ts.map +1 -0
- package/lib/components/settings/SupportSection.jsx +22 -0
- package/lib/components/settings/SupportSection.jsx.map +1 -0
- package/lib/components/settings/index.d.ts +5 -0
- package/lib/components/settings/index.d.ts.map +1 -0
- package/lib/components/settings/index.js +5 -0
- package/lib/components/settings/index.js.map +1 -0
- package/lib/components/settings-row.d.ts +28 -0
- package/lib/components/settings-row.d.ts.map +1 -0
- package/lib/components/settings-row.jsx +68 -0
- package/lib/components/settings-row.jsx.map +1 -0
- package/lib/components/skeleton.d.ts +8 -0
- package/lib/components/skeleton.d.ts.map +1 -0
- package/lib/components/skeleton.jsx +24 -0
- package/lib/components/skeleton.jsx.map +1 -0
- package/lib/components/social-connections.d.ts +15 -0
- package/lib/components/social-connections.d.ts.map +1 -0
- package/lib/components/social-connections.jsx +31 -0
- package/lib/components/social-connections.jsx.map +1 -0
- package/lib/components/stat-card.d.ts +29 -0
- package/lib/components/stat-card.d.ts.map +1 -0
- package/lib/components/stat-card.jsx +36 -0
- package/lib/components/stat-card.jsx.map +1 -0
- package/lib/components/tag-chip.d.ts +18 -0
- package/lib/components/tag-chip.d.ts.map +1 -0
- package/lib/components/tag-chip.jsx +54 -0
- package/lib/components/tag-chip.jsx.map +1 -0
- package/lib/components/tag-multi-select.d.ts +27 -0
- package/lib/components/tag-multi-select.d.ts.map +1 -0
- package/lib/components/tag-multi-select.jsx +65 -0
- package/lib/components/tag-multi-select.jsx.map +1 -0
- package/lib/components/text.d.ts +22 -0
- package/lib/components/text.d.ts.map +1 -0
- package/lib/components/text.jsx +43 -0
- package/lib/components/text.jsx.map +1 -0
- package/lib/components/toast/ToastPortal.d.ts +11 -0
- package/lib/components/toast/ToastPortal.d.ts.map +1 -0
- package/lib/components/toast/ToastPortal.jsx +15 -0
- package/lib/components/toast/ToastPortal.jsx.map +1 -0
- package/lib/components/toast/ToastPortal.web.d.ts +14 -0
- package/lib/components/toast/ToastPortal.web.d.ts.map +1 -0
- package/lib/components/toast/ToastPortal.web.jsx +39 -0
- package/lib/components/toast/ToastPortal.web.jsx.map +1 -0
- package/lib/components/toast/index.d.ts +3 -0
- package/lib/components/toast/index.d.ts.map +1 -0
- package/lib/components/toast/index.js +3 -0
- package/lib/components/toast/index.js.map +1 -0
- package/lib/components/toast/toast-config.d.ts +14 -0
- package/lib/components/toast/toast-config.d.ts.map +1 -0
- package/lib/components/toast/toast-config.jsx +24 -0
- package/lib/components/toast/toast-config.jsx.map +1 -0
- package/lib/components/tooltip.d.ts +30 -0
- package/lib/components/tooltip.d.ts.map +1 -0
- package/lib/components/tooltip.jsx +14 -0
- package/lib/components/tooltip.jsx.map +1 -0
- package/lib/components/totp-display.d.ts +23 -0
- package/lib/components/totp-display.d.ts.map +1 -0
- package/lib/components/totp-display.jsx +132 -0
- package/lib/components/totp-display.jsx.map +1 -0
- package/lib/components/user-avatar.d.ts +18 -0
- package/lib/components/user-avatar.d.ts.map +1 -0
- package/lib/components/user-avatar.jsx +25 -0
- package/lib/components/user-avatar.jsx.map +1 -0
- package/lib/context/AppConfigContext.d.ts +56 -0
- package/lib/context/AppConfigContext.d.ts.map +1 -0
- package/lib/context/AppConfigContext.jsx +14 -0
- package/lib/context/AppConfigContext.jsx.map +1 -0
- package/lib/context/NavigationContext.d.ts +42 -0
- package/lib/context/NavigationContext.d.ts.map +1 -0
- package/lib/context/NavigationContext.jsx +53 -0
- package/lib/context/NavigationContext.jsx.map +1 -0
- package/lib/context/NotificationContext.d.ts +32 -0
- package/lib/context/NotificationContext.d.ts.map +1 -0
- package/lib/context/NotificationContext.jsx +49 -0
- package/lib/context/NotificationContext.jsx.map +1 -0
- package/lib/context/ThemeContext.d.ts +12 -0
- package/lib/context/ThemeContext.d.ts.map +1 -0
- package/lib/context/ThemeContext.jsx +66 -0
- package/lib/context/ThemeContext.jsx.map +1 -0
- package/lib/context/index.d.ts +5 -0
- package/lib/context/index.d.ts.map +1 -0
- package/lib/context/index.js +5 -0
- package/lib/context/index.js.map +1 -0
- package/lib/flags.d.ts +9 -0
- package/lib/flags.d.ts.map +1 -0
- package/lib/flags.js +37 -0
- package/lib/flags.js.map +1 -0
- package/lib/forms/form-error.d.ts +12 -0
- package/lib/forms/form-error.d.ts.map +1 -0
- package/lib/forms/form-error.jsx +14 -0
- package/lib/forms/form-error.jsx.map +1 -0
- package/lib/forms/index.d.ts +3 -0
- package/lib/forms/index.d.ts.map +1 -0
- package/lib/forms/index.js +3 -0
- package/lib/forms/index.js.map +1 -0
- package/lib/forms/shake-field.d.ts +18 -0
- package/lib/forms/shake-field.d.ts.map +1 -0
- package/lib/forms/shake-field.jsx +30 -0
- package/lib/forms/shake-field.jsx.map +1 -0
- package/lib/hooks/index.d.ts +6 -0
- package/lib/hooks/index.d.ts.map +1 -0
- package/lib/hooks/index.js +6 -0
- package/lib/hooks/index.js.map +1 -0
- package/lib/hooks/useAuth.d.ts +109 -0
- package/lib/hooks/useAuth.d.ts.map +1 -0
- package/lib/hooks/useAuth.jsx +404 -0
- package/lib/hooks/useAuth.jsx.map +1 -0
- package/lib/hooks/useAutoLock.d.ts +22 -0
- package/lib/hooks/useAutoLock.d.ts.map +1 -0
- package/lib/hooks/useAutoLock.js +85 -0
- package/lib/hooks/useAutoLock.js.map +1 -0
- package/lib/hooks/useDebouncedValue.d.ts +19 -0
- package/lib/hooks/useDebouncedValue.d.ts.map +1 -0
- package/lib/hooks/useDebouncedValue.js +29 -0
- package/lib/hooks/useDebouncedValue.js.map +1 -0
- package/lib/hooks/useShakeAnimation.d.ts +17 -0
- package/lib/hooks/useShakeAnimation.d.ts.map +1 -0
- package/lib/hooks/useShakeAnimation.js +22 -0
- package/lib/hooks/useShakeAnimation.js.map +1 -0
- package/lib/hooks/useUploadBlobUrl.d.ts +13 -0
- package/lib/hooks/useUploadBlobUrl.d.ts.map +1 -0
- package/lib/hooks/useUploadBlobUrl.js +60 -0
- package/lib/hooks/useUploadBlobUrl.js.map +1 -0
- package/lib/index.d.ts +10 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +47 -0
- package/lib/index.js.map +1 -0
- package/lib/screens/auth/AccountPickerScreen.d.ts +24 -0
- package/lib/screens/auth/AccountPickerScreen.d.ts.map +1 -0
- package/lib/screens/auth/AccountPickerScreen.jsx +47 -0
- package/lib/screens/auth/AccountPickerScreen.jsx.map +1 -0
- package/lib/screens/auth/AuthScreen.d.ts +59 -0
- package/lib/screens/auth/AuthScreen.d.ts.map +1 -0
- package/lib/screens/auth/AuthScreen.jsx +594 -0
- package/lib/screens/auth/AuthScreen.jsx.map +1 -0
- package/lib/screens/auth/ConsentScreen.d.ts +27 -0
- package/lib/screens/auth/ConsentScreen.d.ts.map +1 -0
- package/lib/screens/auth/ConsentScreen.jsx +55 -0
- package/lib/screens/auth/ConsentScreen.jsx.map +1 -0
- package/lib/screens/auth/ErrorScreen.d.ts +20 -0
- package/lib/screens/auth/ErrorScreen.d.ts.map +1 -0
- package/lib/screens/auth/ErrorScreen.jsx +43 -0
- package/lib/screens/auth/ErrorScreen.jsx.map +1 -0
- package/lib/screens/auth/ExpiredLinkScreen.d.ts +19 -0
- package/lib/screens/auth/ExpiredLinkScreen.d.ts.map +1 -0
- package/lib/screens/auth/ExpiredLinkScreen.jsx +38 -0
- package/lib/screens/auth/ExpiredLinkScreen.jsx.map +1 -0
- package/lib/screens/auth/ForgotPasswordScreen.d.ts +4 -0
- package/lib/screens/auth/ForgotPasswordScreen.d.ts.map +1 -0
- package/lib/screens/auth/ForgotPasswordScreen.jsx +123 -0
- package/lib/screens/auth/ForgotPasswordScreen.jsx.map +1 -0
- package/lib/screens/auth/ImportDataScreen.d.ts +17 -0
- package/lib/screens/auth/ImportDataScreen.d.ts.map +1 -0
- package/lib/screens/auth/ImportDataScreen.jsx +73 -0
- package/lib/screens/auth/ImportDataScreen.jsx.map +1 -0
- package/lib/screens/auth/LoginScreen.d.ts +38 -0
- package/lib/screens/auth/LoginScreen.d.ts.map +1 -0
- package/lib/screens/auth/LoginScreen.jsx +326 -0
- package/lib/screens/auth/LoginScreen.jsx.map +1 -0
- package/lib/screens/auth/MfaChallengeScreen.d.ts +4 -0
- package/lib/screens/auth/MfaChallengeScreen.d.ts.map +1 -0
- package/lib/screens/auth/MfaChallengeScreen.jsx +139 -0
- package/lib/screens/auth/MfaChallengeScreen.jsx.map +1 -0
- package/lib/screens/auth/MfaEnrollScreen.d.ts +12 -0
- package/lib/screens/auth/MfaEnrollScreen.d.ts.map +1 -0
- package/lib/screens/auth/MfaEnrollScreen.jsx +267 -0
- package/lib/screens/auth/MfaEnrollScreen.jsx.map +1 -0
- package/lib/screens/auth/PasskeyEnrollScreen.d.ts +18 -0
- package/lib/screens/auth/PasskeyEnrollScreen.d.ts.map +1 -0
- package/lib/screens/auth/PasskeyEnrollScreen.jsx +51 -0
- package/lib/screens/auth/PasskeyEnrollScreen.jsx.map +1 -0
- package/lib/screens/auth/PrivacyPolicyScreen.d.ts +19 -0
- package/lib/screens/auth/PrivacyPolicyScreen.d.ts.map +1 -0
- package/lib/screens/auth/PrivacyPolicyScreen.jsx +143 -0
- package/lib/screens/auth/PrivacyPolicyScreen.jsx.map +1 -0
- package/lib/screens/auth/RegisterScreen.d.ts +14 -0
- package/lib/screens/auth/RegisterScreen.d.ts.map +1 -0
- package/lib/screens/auth/RegisterScreen.jsx +296 -0
- package/lib/screens/auth/RegisterScreen.jsx.map +1 -0
- package/lib/screens/auth/ResetPasswordScreen.d.ts +12 -0
- package/lib/screens/auth/ResetPasswordScreen.d.ts.map +1 -0
- package/lib/screens/auth/ResetPasswordScreen.jsx +276 -0
- package/lib/screens/auth/ResetPasswordScreen.jsx.map +1 -0
- package/lib/screens/auth/ServerConfigScreen.d.ts +18 -0
- package/lib/screens/auth/ServerConfigScreen.d.ts.map +1 -0
- package/lib/screens/auth/ServerConfigScreen.jsx +259 -0
- package/lib/screens/auth/ServerConfigScreen.jsx.map +1 -0
- package/lib/screens/auth/TermsOfServiceScreen.d.ts +30 -0
- package/lib/screens/auth/TermsOfServiceScreen.d.ts.map +1 -0
- package/lib/screens/auth/TermsOfServiceScreen.jsx +130 -0
- package/lib/screens/auth/TermsOfServiceScreen.jsx.map +1 -0
- package/lib/screens/auth/VerifyEmailScreen.d.ts +4 -0
- package/lib/screens/auth/VerifyEmailScreen.d.ts.map +1 -0
- package/lib/screens/auth/VerifyEmailScreen.jsx +249 -0
- package/lib/screens/auth/VerifyEmailScreen.jsx.map +1 -0
- package/lib/screens/auth/WelcomeScreen.d.ts +17 -0
- package/lib/screens/auth/WelcomeScreen.d.ts.map +1 -0
- package/lib/screens/auth/WelcomeScreen.jsx +58 -0
- package/lib/screens/auth/WelcomeScreen.jsx.map +1 -0
- package/lib/screens/auth/index.d.ts +19 -0
- package/lib/screens/auth/index.d.ts.map +1 -0
- package/lib/screens/auth/index.js +19 -0
- package/lib/screens/auth/index.js.map +1 -0
- package/lib/screens/index.d.ts +2 -0
- package/lib/screens/index.d.ts.map +1 -0
- package/lib/screens/index.js +2 -0
- package/lib/screens/index.js.map +1 -0
- package/lib/services/api-config.d.ts +87 -0
- package/lib/services/api-config.d.ts.map +1 -0
- package/lib/services/api-config.js +202 -0
- package/lib/services/api-config.js.map +1 -0
- package/lib/services/auth.service.d.ts +140 -0
- package/lib/services/auth.service.d.ts.map +1 -0
- package/lib/services/auth.service.js +376 -0
- package/lib/services/auth.service.js.map +1 -0
- package/lib/services/favicon.d.ts +46 -0
- package/lib/services/favicon.d.ts.map +1 -0
- package/lib/services/favicon.js +84 -0
- package/lib/services/favicon.js.map +1 -0
- package/lib/services/hibp-cache.d.ts +23 -0
- package/lib/services/hibp-cache.d.ts.map +1 -0
- package/lib/services/hibp-cache.js +56 -0
- package/lib/services/hibp-cache.js.map +1 -0
- package/lib/services/hibp.d.ts +28 -0
- package/lib/services/hibp.d.ts.map +1 -0
- package/lib/services/hibp.js +92 -0
- package/lib/services/hibp.js.map +1 -0
- package/lib/services/index.d.ts +8 -0
- package/lib/services/index.d.ts.map +1 -0
- package/lib/services/index.js +7 -0
- package/lib/services/index.js.map +1 -0
- package/lib/services/passkey.d.ts +10 -0
- package/lib/services/passkey.d.ts.map +1 -0
- package/lib/services/passkey.js +192 -0
- package/lib/services/passkey.js.map +1 -0
- package/lib/utils/api-fetch.d.ts +11 -0
- package/lib/utils/api-fetch.d.ts.map +1 -0
- package/lib/utils/api-fetch.js +52 -0
- package/lib/utils/api-fetch.js.map +1 -0
- package/lib/utils/clipboard.d.ts +31 -0
- package/lib/utils/clipboard.d.ts.map +1 -0
- package/lib/utils/clipboard.js +66 -0
- package/lib/utils/clipboard.js.map +1 -0
- package/lib/utils/cn.d.ts +9 -0
- package/lib/utils/cn.d.ts.map +1 -0
- package/lib/utils/cn.js +12 -0
- package/lib/utils/cn.js.map +1 -0
- package/lib/utils/debounce.d.ts +13 -0
- package/lib/utils/debounce.d.ts.map +1 -0
- package/lib/utils/debounce.js +28 -0
- package/lib/utils/debounce.js.map +1 -0
- package/lib/utils/error.d.ts +9 -0
- package/lib/utils/error.d.ts.map +1 -0
- package/lib/utils/error.js +11 -0
- package/lib/utils/error.js.map +1 -0
- package/lib/utils/fetch.d.ts +17 -0
- package/lib/utils/fetch.d.ts.map +1 -0
- package/lib/utils/fetch.js +29 -0
- package/lib/utils/fetch.js.map +1 -0
- package/lib/utils/http-error.d.ts +41 -0
- package/lib/utils/http-error.d.ts.map +1 -0
- package/lib/utils/http-error.js +63 -0
- package/lib/utils/http-error.js.map +1 -0
- package/lib/utils/index.d.ts +11 -0
- package/lib/utils/index.d.ts.map +1 -0
- package/lib/utils/index.js +11 -0
- package/lib/utils/index.js.map +1 -0
- package/lib/utils/palette.d.ts +46 -0
- package/lib/utils/palette.d.ts.map +1 -0
- package/lib/utils/palette.js +75 -0
- package/lib/utils/palette.js.map +1 -0
- package/lib/utils/password.d.ts +20 -0
- package/lib/utils/password.d.ts.map +1 -0
- package/lib/utils/password.js +51 -0
- package/lib/utils/password.js.map +1 -0
- package/lib/utils/settings-storage.d.ts +3 -0
- package/lib/utils/settings-storage.d.ts.map +1 -0
- package/lib/utils/settings-storage.js +62 -0
- package/lib/utils/settings-storage.js.map +1 -0
- package/lib/utils/validation.d.ts +29 -0
- package/lib/utils/validation.d.ts.map +1 -0
- package/lib/utils/validation.js +58 -0
- package/lib/utils/validation.js.map +1 -0
- package/package.json +204 -0
- package/src/components/__tests__/data-table.test.ts +94 -0
- package/src/components/__tests__/pagination.test.ts +73 -0
- package/src/components/__tests__/stat-card.test.ts +21 -0
- package/src/components/auth/LockOverlay.tsx +122 -0
- package/src/components/auth/PasswordStrengthMeter.tsx +96 -0
- package/src/components/auth/ProtectedRoute.tsx +91 -0
- package/src/components/auth/PwnedPasswordWarning.tsx +54 -0
- package/src/components/auth/index.ts +10 -0
- package/src/components/bottom-nav.tsx +99 -0
- package/src/components/button.tsx +144 -0
- package/src/components/card.tsx +82 -0
- package/src/components/checkbox.tsx +48 -0
- package/src/components/connection-settings.tsx +583 -0
- package/src/components/context-menu.tsx +95 -0
- package/src/components/data-table.tsx +223 -0
- package/src/components/dialog.tsx +376 -0
- package/src/components/dropdown-menu.tsx +120 -0
- package/src/components/entropy-boot-splash.tsx +114 -0
- package/src/components/entropy-mark-animated.tsx +260 -0
- package/src/components/entropy-mark-geometry.ts +11 -0
- package/src/components/entropy-mark-sequential.tsx +132 -0
- package/src/components/entropy-mark.tsx +135 -0
- package/src/components/error-boundary.tsx +70 -0
- package/src/components/index.ts +156 -0
- package/src/components/input.tsx +246 -0
- package/src/components/item-icon.tsx +111 -0
- package/src/components/label.tsx +25 -0
- package/src/components/legal-dialog.tsx +47 -0
- package/src/components/license-gate.tsx +28 -0
- package/src/components/logo.tsx +34 -0
- package/src/components/onboarding-wizard.tsx +353 -0
- package/src/components/pagination.tsx +154 -0
- package/src/components/password-generator.tsx +393 -0
- package/src/components/pin-pad.tsx +156 -0
- package/src/components/popover.tsx +38 -0
- package/src/components/profile/ProfileDialog.tsx +129 -0
- package/src/components/profile/ProfileTab.tsx +151 -0
- package/src/components/profile/SecurityTab.tsx +229 -0
- package/src/components/profile/index.ts +3 -0
- package/src/components/segmented-toggle.tsx +119 -0
- package/src/components/separator.tsx +41 -0
- package/src/components/server-settings.tsx +442 -0
- package/src/components/settings/AccountSection.tsx +76 -0
- package/src/components/settings/DangerZoneSection.tsx +37 -0
- package/src/components/settings/GeneralSection.tsx +39 -0
- package/src/components/settings/SupportSection.tsx +53 -0
- package/src/components/settings/index.ts +4 -0
- package/src/components/settings-row.tsx +126 -0
- package/src/components/skeleton.tsx +48 -0
- package/src/components/social-connections.tsx +55 -0
- package/src/components/stat-card.tsx +64 -0
- package/src/components/tag-chip.tsx +78 -0
- package/src/components/tag-multi-select.tsx +136 -0
- package/src/components/text.tsx +77 -0
- package/src/components/toast/ToastPortal.tsx +16 -0
- package/src/components/toast/ToastPortal.web.tsx +47 -0
- package/src/components/toast/index.ts +2 -0
- package/src/components/toast/toast-config.tsx +31 -0
- package/src/components/tooltip.tsx +30 -0
- package/src/components/totp-display.tsx +207 -0
- package/src/components/user-avatar.tsx +46 -0
- package/src/context/AppConfigContext.tsx +76 -0
- package/src/context/NavigationContext.tsx +75 -0
- package/src/context/NotificationContext.tsx +69 -0
- package/src/context/ThemeContext.tsx +83 -0
- package/src/context/__tests__/NavigationContext.test.tsx +53 -0
- package/src/context/index.ts +24 -0
- package/src/flags.ts +44 -0
- package/src/forms/form-error.tsx +20 -0
- package/src/forms/index.ts +2 -0
- package/src/forms/shake-field.tsx +52 -0
- package/src/hooks/__tests__/useUploadBlobUrl.test.tsx +77 -0
- package/src/hooks/index.ts +18 -0
- package/src/hooks/useAuth.tsx +567 -0
- package/src/hooks/useAutoLock.ts +110 -0
- package/src/hooks/useDebouncedValue.ts +32 -0
- package/src/hooks/useShakeAnimation.ts +42 -0
- package/src/hooks/useUploadBlobUrl.ts +75 -0
- package/src/index.ts +48 -0
- package/src/screens/auth/AccountPickerScreen.tsx +103 -0
- package/src/screens/auth/AuthScreen.tsx +941 -0
- package/src/screens/auth/ConsentScreen.tsx +118 -0
- package/src/screens/auth/ErrorScreen.tsx +96 -0
- package/src/screens/auth/ExpiredLinkScreen.tsx +87 -0
- package/src/screens/auth/ForgotPasswordScreen.tsx +182 -0
- package/src/screens/auth/ImportDataScreen.tsx +112 -0
- package/src/screens/auth/LoginScreen.tsx +484 -0
- package/src/screens/auth/MfaChallengeScreen.tsx +216 -0
- package/src/screens/auth/MfaEnrollScreen.tsx +388 -0
- package/src/screens/auth/PasskeyEnrollScreen.tsx +96 -0
- package/src/screens/auth/PrivacyPolicyScreen.tsx +249 -0
- package/src/screens/auth/RegisterScreen.tsx +430 -0
- package/src/screens/auth/ResetPasswordScreen.tsx +377 -0
- package/src/screens/auth/ServerConfigScreen.tsx +388 -0
- package/src/screens/auth/TermsOfServiceScreen.tsx +236 -0
- package/src/screens/auth/VerifyEmailScreen.tsx +310 -0
- package/src/screens/auth/WelcomeScreen.tsx +78 -0
- package/src/screens/auth/index.ts +36 -0
- package/src/screens/index.ts +1 -0
- package/src/services/__tests__/api-config.test.ts +67 -0
- package/src/services/__tests__/favicon.test.ts +88 -0
- package/src/services/__tests__/hibp-cache.test.ts +37 -0
- package/src/services/__tests__/hibp.test.ts +39 -0
- package/src/services/api-config.ts +260 -0
- package/src/services/auth.service.ts +498 -0
- package/src/services/favicon.ts +102 -0
- package/src/services/hibp-cache.ts +71 -0
- package/src/services/hibp.ts +120 -0
- package/src/services/index.ts +52 -0
- package/src/services/passkey.ts +213 -0
- package/src/types/external.d.ts +24 -0
- package/src/utils/__tests__/clipboard.test.ts +59 -0
- package/src/utils/__tests__/cn.test.ts +24 -0
- package/src/utils/__tests__/debounce.test.ts +42 -0
- package/src/utils/__tests__/error.test.ts +18 -0
- package/src/utils/__tests__/http-error.test.ts +33 -0
- package/src/utils/__tests__/palette.test.ts +22 -0
- package/src/utils/__tests__/password.test.ts +55 -0
- package/src/utils/__tests__/settings-storage.test.ts +15 -0
- package/src/utils/__tests__/validation.test.ts +52 -0
- package/src/utils/api-fetch.ts +61 -0
- package/src/utils/clipboard.ts +69 -0
- package/src/utils/cn.ts +12 -0
- package/src/utils/debounce.ts +33 -0
- package/src/utils/error.ts +10 -0
- package/src/utils/fetch.ts +33 -0
- package/src/utils/http-error.ts +81 -0
- package/src/utils/index.ts +23 -0
- package/src/utils/palette.ts +105 -0
- package/src/utils/password.ts +64 -0
- package/src/utils/settings-storage.ts +68 -0
- package/src/utils/validation.ts +71 -0
- package/styles/globals.css +262 -0
- package/tailwind-preset.js +163 -0
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import * as DropdownMenuPrimitive from "@rn-primitives/dropdown-menu";
|
|
2
|
+
import { cn } from "../utils/cn";
|
|
3
|
+
import React from "react";
|
|
4
|
+
import { Platform, View, type ViewStyle } from "react-native";
|
|
5
|
+
|
|
6
|
+
const DropdownMenu = DropdownMenuPrimitive.Root;
|
|
7
|
+
const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger;
|
|
8
|
+
|
|
9
|
+
const DropdownMenuContent = React.forwardRef<
|
|
10
|
+
React.ElementRef<typeof DropdownMenuPrimitive.Content>,
|
|
11
|
+
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Content>
|
|
12
|
+
>(({ className, sideOffset = 4, ...props }, ref) => {
|
|
13
|
+
const content = (
|
|
14
|
+
<DropdownMenuPrimitive.Content
|
|
15
|
+
ref={ref}
|
|
16
|
+
sideOffset={sideOffset}
|
|
17
|
+
className={cn(
|
|
18
|
+
"z-50 min-w-[8rem] overflow-hidden rounded-md border border-border bg-popover p-1",
|
|
19
|
+
className
|
|
20
|
+
)}
|
|
21
|
+
style={
|
|
22
|
+
Platform.OS === "web"
|
|
23
|
+
? ({ boxShadow: "0px 4px 12px rgba(0, 0, 0, 0.15)" } as ViewStyle &
|
|
24
|
+
Record<string, unknown>)
|
|
25
|
+
: undefined
|
|
26
|
+
}
|
|
27
|
+
{...props}
|
|
28
|
+
/>
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
if (Platform.OS === "web") {
|
|
32
|
+
// On web, Portal expects exactly one child — skip the Overlay (Radix
|
|
33
|
+
// handles dismiss-on-click-outside internally).
|
|
34
|
+
return <DropdownMenuPrimitive.Portal>{content}</DropdownMenuPrimitive.Portal>;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return (
|
|
38
|
+
<DropdownMenuPrimitive.Portal>
|
|
39
|
+
<DropdownMenuPrimitive.Overlay className="animate-in fade-in-0" />
|
|
40
|
+
{content}
|
|
41
|
+
</DropdownMenuPrimitive.Portal>
|
|
42
|
+
);
|
|
43
|
+
});
|
|
44
|
+
DropdownMenuContent.displayName = "DropdownMenuContent";
|
|
45
|
+
|
|
46
|
+
const DropdownMenuItem = React.forwardRef<
|
|
47
|
+
React.ElementRef<typeof DropdownMenuPrimitive.Item>,
|
|
48
|
+
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Item>
|
|
49
|
+
>(({ className, ...props }, ref) => (
|
|
50
|
+
<DropdownMenuPrimitive.Item
|
|
51
|
+
ref={ref}
|
|
52
|
+
className={cn(
|
|
53
|
+
"relative flex flex-row items-center rounded-sm px-2 py-1.5 web:cursor-pointer web:outline-none active:bg-accent",
|
|
54
|
+
"web:hover:bg-accent web:focus:bg-accent",
|
|
55
|
+
props.disabled && "opacity-50 web:pointer-events-none",
|
|
56
|
+
className
|
|
57
|
+
)}
|
|
58
|
+
{...props}
|
|
59
|
+
/>
|
|
60
|
+
));
|
|
61
|
+
DropdownMenuItem.displayName = "DropdownMenuItem";
|
|
62
|
+
|
|
63
|
+
const DropdownMenuCheckboxItem = React.forwardRef<
|
|
64
|
+
React.ElementRef<typeof DropdownMenuPrimitive.CheckboxItem>,
|
|
65
|
+
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.CheckboxItem>
|
|
66
|
+
>(({ className, children, checked, ...props }, ref) => (
|
|
67
|
+
<DropdownMenuPrimitive.CheckboxItem
|
|
68
|
+
ref={ref}
|
|
69
|
+
className={cn(
|
|
70
|
+
"relative flex flex-row items-center rounded-sm py-1.5 pl-8 pr-2 web:cursor-pointer web:outline-none active:bg-accent",
|
|
71
|
+
"web:hover:bg-accent web:focus:bg-accent",
|
|
72
|
+
props.disabled && "opacity-50 web:pointer-events-none",
|
|
73
|
+
className
|
|
74
|
+
)}
|
|
75
|
+
checked={checked}
|
|
76
|
+
{...props}
|
|
77
|
+
>
|
|
78
|
+
<View className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
|
|
79
|
+
<DropdownMenuPrimitive.ItemIndicator>
|
|
80
|
+
{/* Checkmark indicator */}
|
|
81
|
+
</DropdownMenuPrimitive.ItemIndicator>
|
|
82
|
+
</View>
|
|
83
|
+
{children as React.ReactNode}
|
|
84
|
+
</DropdownMenuPrimitive.CheckboxItem>
|
|
85
|
+
));
|
|
86
|
+
DropdownMenuCheckboxItem.displayName = "DropdownMenuCheckboxItem";
|
|
87
|
+
|
|
88
|
+
const DropdownMenuLabel = React.forwardRef<
|
|
89
|
+
React.ElementRef<typeof DropdownMenuPrimitive.Label>,
|
|
90
|
+
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Label>
|
|
91
|
+
>(({ className, ...props }, ref) => (
|
|
92
|
+
<DropdownMenuPrimitive.Label
|
|
93
|
+
ref={ref}
|
|
94
|
+
className={cn("px-2 py-1.5 text-sm font-semibold text-foreground", className)}
|
|
95
|
+
{...props}
|
|
96
|
+
/>
|
|
97
|
+
));
|
|
98
|
+
DropdownMenuLabel.displayName = "DropdownMenuLabel";
|
|
99
|
+
|
|
100
|
+
const DropdownMenuSeparator = React.forwardRef<
|
|
101
|
+
React.ElementRef<typeof DropdownMenuPrimitive.Separator>,
|
|
102
|
+
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Separator>
|
|
103
|
+
>(({ className, ...props }, ref) => (
|
|
104
|
+
<DropdownMenuPrimitive.Separator
|
|
105
|
+
ref={ref}
|
|
106
|
+
className={cn("-mx-1 my-1 h-px bg-border", className)}
|
|
107
|
+
{...props}
|
|
108
|
+
/>
|
|
109
|
+
));
|
|
110
|
+
DropdownMenuSeparator.displayName = "DropdownMenuSeparator";
|
|
111
|
+
|
|
112
|
+
export {
|
|
113
|
+
DropdownMenu,
|
|
114
|
+
DropdownMenuTrigger,
|
|
115
|
+
DropdownMenuContent,
|
|
116
|
+
DropdownMenuItem,
|
|
117
|
+
DropdownMenuCheckboxItem,
|
|
118
|
+
DropdownMenuLabel,
|
|
119
|
+
DropdownMenuSeparator,
|
|
120
|
+
};
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import React, { useEffect, useRef } from "react";
|
|
2
|
+
import { Animated, Easing, Platform, StyleSheet, View } from "react-native";
|
|
3
|
+
import { useColorScheme } from "nativewind";
|
|
4
|
+
import Svg, { Path } from "react-native-svg";
|
|
5
|
+
import { ENTROPY_MARK_ASPECT, ENTROPY_MARK_PATH, ENTROPY_MARK_VIEWBOX } from "./entropy-mark";
|
|
6
|
+
import { usePalette } from "../utils/palette";
|
|
7
|
+
import { DISABLE_BRANDING } from "../flags";
|
|
8
|
+
|
|
9
|
+
// Web has no native animated module; requesting the native driver there just
|
|
10
|
+
// warns and falls back to JS. Gate it so the console stays clean.
|
|
11
|
+
const USE_NATIVE_DRIVER = Platform.OS !== "web";
|
|
12
|
+
|
|
13
|
+
export interface EntropyBootSplashProps {
|
|
14
|
+
/** Called once the intro + hold + fade-out finishes. */
|
|
15
|
+
onFinish?: () => void;
|
|
16
|
+
/** Mark height in px. */
|
|
17
|
+
size?: number;
|
|
18
|
+
/** "chroma" (default) shows the faint cyan/red fringe; "mono" is plain. */
|
|
19
|
+
variant?: "mono" | "chroma";
|
|
20
|
+
/** Override background; defaults to themed near-black / white. */
|
|
21
|
+
background?: string;
|
|
22
|
+
/** ms to hold fully-drifted before fading out. Default 550. */
|
|
23
|
+
holdMs?: number;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Company boot splash — the website's logo motion as a launch animation: the
|
|
28
|
+
* mark fades in flat, the three echoes drift apart + breathe (driven by
|
|
29
|
+
* EntropyMarkAnimated's `active` state — the same motion source as the
|
|
30
|
+
* website hover), hold, then the whole thing fades out and calls `onFinish`.
|
|
31
|
+
* Subtle corporate recognition at launch; each product keeps its own
|
|
32
|
+
* icon/splash for the OS-level launch screen — this is an in-app overlay.
|
|
33
|
+
*/
|
|
34
|
+
export function EntropyBootSplash({
|
|
35
|
+
onFinish,
|
|
36
|
+
size = 96,
|
|
37
|
+
// `variant` is retained on the props interface for API compatibility but the
|
|
38
|
+
// current flat-mark splash renders the same regardless, so it isn't read.
|
|
39
|
+
background,
|
|
40
|
+
holdMs = 550,
|
|
41
|
+
}: EntropyBootSplashProps) {
|
|
42
|
+
const { colorScheme } = useColorScheme();
|
|
43
|
+
const isDark = colorScheme === "dark";
|
|
44
|
+
const { palette } = usePalette();
|
|
45
|
+
// Match the app's themed background exactly (bg-background) so there's no
|
|
46
|
+
// color seam when the splash dismisses into the screen behind it.
|
|
47
|
+
const bg = background ?? palette.background;
|
|
48
|
+
|
|
49
|
+
const fade = useRef(new Animated.Value(0)).current;
|
|
50
|
+
|
|
51
|
+
useEffect(() => {
|
|
52
|
+
// Self-host branding opt-out: skip the splash entirely, let the app proceed.
|
|
53
|
+
if (DISABLE_BRANDING) {
|
|
54
|
+
onFinish?.();
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
const anim = Animated.sequence([
|
|
58
|
+
Animated.timing(fade, {
|
|
59
|
+
toValue: 1,
|
|
60
|
+
duration: 320,
|
|
61
|
+
easing: Easing.out(Easing.quad),
|
|
62
|
+
useNativeDriver: USE_NATIVE_DRIVER,
|
|
63
|
+
}),
|
|
64
|
+
// mark's own open-ease (~450ms) + breathing run during the hold
|
|
65
|
+
Animated.delay(900 + holdMs),
|
|
66
|
+
Animated.timing(fade, {
|
|
67
|
+
toValue: 0,
|
|
68
|
+
duration: 420,
|
|
69
|
+
easing: Easing.in(Easing.quad),
|
|
70
|
+
useNativeDriver: USE_NATIVE_DRIVER,
|
|
71
|
+
}),
|
|
72
|
+
]);
|
|
73
|
+
anim.start(({ finished }) => {
|
|
74
|
+
if (finished) {
|
|
75
|
+
onFinish?.();
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
return () => anim.stop();
|
|
79
|
+
// run once on mount
|
|
80
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
81
|
+
}, []);
|
|
82
|
+
|
|
83
|
+
if (DISABLE_BRANDING) {
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return (
|
|
88
|
+
<View
|
|
89
|
+
style={[
|
|
90
|
+
StyleSheet.absoluteFill,
|
|
91
|
+
{
|
|
92
|
+
backgroundColor: bg,
|
|
93
|
+
alignItems: "center",
|
|
94
|
+
justifyContent: "center",
|
|
95
|
+
pointerEvents: "none",
|
|
96
|
+
},
|
|
97
|
+
]}
|
|
98
|
+
>
|
|
99
|
+
{/* Static flat source mark — the topmost layer only, monochromatic to the
|
|
100
|
+
theme (black in light, white in dark). No echoes, no motion. */}
|
|
101
|
+
<Animated.View style={{ opacity: fade }}>
|
|
102
|
+
<Svg
|
|
103
|
+
width={Math.round(size * ENTROPY_MARK_ASPECT)}
|
|
104
|
+
height={size}
|
|
105
|
+
viewBox={ENTROPY_MARK_VIEWBOX}
|
|
106
|
+
>
|
|
107
|
+
<Path d={ENTROPY_MARK_PATH} fillRule="evenodd" fill={isDark ? "#ffffff" : "#000000"} />
|
|
108
|
+
</Svg>
|
|
109
|
+
</Animated.View>
|
|
110
|
+
</View>
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export default EntropyBootSplash;
|
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
import React, { useEffect } from "react";
|
|
2
|
+
import { View, type GestureResponderEvent } from "react-native";
|
|
3
|
+
import Svg, { Path } from "react-native-svg";
|
|
4
|
+
import Animated, {
|
|
5
|
+
Easing,
|
|
6
|
+
ReduceMotion,
|
|
7
|
+
useAnimatedStyle,
|
|
8
|
+
useSharedValue,
|
|
9
|
+
withDelay,
|
|
10
|
+
withRepeat,
|
|
11
|
+
withSequence,
|
|
12
|
+
withTiming,
|
|
13
|
+
type SharedValue,
|
|
14
|
+
} from "react-native-reanimated";
|
|
15
|
+
import { useColorScheme } from "nativewind";
|
|
16
|
+
import {
|
|
17
|
+
ENTROPY_MARK_ASPECT,
|
|
18
|
+
ENTROPY_MARK_PATH,
|
|
19
|
+
ENTROPY_MARK_STEP,
|
|
20
|
+
ENTROPY_MARK_VIEWBOX,
|
|
21
|
+
} from "./entropy-mark-geometry";
|
|
22
|
+
|
|
23
|
+
// React Native port of the website's animated company mark
|
|
24
|
+
// (website/src/components/logo.tsx). Same motion model, hover → touch:
|
|
25
|
+
//
|
|
26
|
+
// • At rest the mark is FLAT — sharp source `>_` only, echoes collapsed
|
|
27
|
+
// underneath it (invisible).
|
|
28
|
+
// • While pressed, `open` eases 0→1: the three grey time-echoes fade in and
|
|
29
|
+
// drift apart, each breathing on its own period/phase so they never move
|
|
30
|
+
// in lockstep (the endless, unevenly-spaced cascade).
|
|
31
|
+
// • Parallax: while pressed, the echoes lean toward the finger (deeper
|
|
32
|
+
// echoes shift more = depth), gated by `open` so it fades with collapse.
|
|
33
|
+
// • On release, `open` eases 1→0 and the echoes resolve cleanly back into
|
|
34
|
+
// the source — no snap.
|
|
35
|
+
// • The sharp source NEVER moves (anchored), and each echo lives on its own
|
|
36
|
+
// Animated.View layer so the source is never re-rasterized mid-animation
|
|
37
|
+
// (the compositor lesson from the web version).
|
|
38
|
+
//
|
|
39
|
+
// Honors the system reduce-motion setting via ReduceMotion.System.
|
|
40
|
+
|
|
41
|
+
// echo keyed by depth (3 = furthest/dimmest .. 1 = nearest the source)
|
|
42
|
+
const PALETTE = {
|
|
43
|
+
light: {
|
|
44
|
+
src: "#000000",
|
|
45
|
+
echo: { 3: "#f5f5f5", 2: "#e2e2e2", 1: "#cbcbcb" },
|
|
46
|
+
cyan: "#0096aa",
|
|
47
|
+
red: "#c82837",
|
|
48
|
+
},
|
|
49
|
+
dark: {
|
|
50
|
+
src: "#ffffff",
|
|
51
|
+
echo: { 3: "#373737", 2: "#5f5f5f", 1: "#8c8c8c" },
|
|
52
|
+
cyan: "#268ca0",
|
|
53
|
+
red: "#a53440",
|
|
54
|
+
},
|
|
55
|
+
} as const;
|
|
56
|
+
|
|
57
|
+
// Matches the web component: breathing reach per echo depth, parallax px per
|
|
58
|
+
// depth-step, breathing period 2.6+i*0.7s with staggered phase.
|
|
59
|
+
const AMP: Record<1 | 2 | 3, number> = { 3: 1.55, 2: 1.4, 1: 1.6 };
|
|
60
|
+
const PX = 9;
|
|
61
|
+
const PY = 7;
|
|
62
|
+
|
|
63
|
+
export interface EntropyMarkAnimatedProps {
|
|
64
|
+
/** Rendered height in px. Width follows the ~1.63:1 aspect. */
|
|
65
|
+
size?: number;
|
|
66
|
+
/** "mono" = grey echoes only; "chroma" = adds the faint cyan/red fringe. */
|
|
67
|
+
variant?: "mono" | "chroma";
|
|
68
|
+
/** Override the theme; defaults to the active color scheme. */
|
|
69
|
+
scheme?: "light" | "dark";
|
|
70
|
+
/** Force the drifted-apart state (e.g. boot splash drives this). */
|
|
71
|
+
active?: boolean;
|
|
72
|
+
/** Drift apart while touched (default true). */
|
|
73
|
+
animateOnPress?: boolean;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function Echo({
|
|
77
|
+
depth,
|
|
78
|
+
fill,
|
|
79
|
+
open,
|
|
80
|
+
px,
|
|
81
|
+
py,
|
|
82
|
+
width,
|
|
83
|
+
height,
|
|
84
|
+
}: {
|
|
85
|
+
depth: 1 | 2 | 3;
|
|
86
|
+
fill: string;
|
|
87
|
+
open: SharedValue<number>;
|
|
88
|
+
px: SharedValue<number>;
|
|
89
|
+
py: SharedValue<number>;
|
|
90
|
+
width: number;
|
|
91
|
+
height: number;
|
|
92
|
+
}) {
|
|
93
|
+
// Breathing oscillator 0..1, own period + phase per depth → desynced.
|
|
94
|
+
const breath = useSharedValue(0);
|
|
95
|
+
useEffect(() => {
|
|
96
|
+
const half = ((2.6 + depth * 0.7) * 1000) / 2;
|
|
97
|
+
const ease = Easing.inOut(Easing.sin);
|
|
98
|
+
breath.value = withDelay(
|
|
99
|
+
depth * 400,
|
|
100
|
+
withRepeat(
|
|
101
|
+
withSequence(
|
|
102
|
+
withTiming(1, { duration: half, easing: ease, reduceMotion: ReduceMotion.System }),
|
|
103
|
+
withTiming(0, { duration: half, easing: ease, reduceMotion: ReduceMotion.System })
|
|
104
|
+
),
|
|
105
|
+
-1,
|
|
106
|
+
false,
|
|
107
|
+
undefined,
|
|
108
|
+
ReduceMotion.System
|
|
109
|
+
)
|
|
110
|
+
);
|
|
111
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
112
|
+
}, [depth]);
|
|
113
|
+
|
|
114
|
+
const style = useAnimatedStyle(() => {
|
|
115
|
+
// Offset = base drift * breathing multiplier (1..AMP) + parallax lean,
|
|
116
|
+
// all scaled by `open` so rest = exactly collapsed under the source.
|
|
117
|
+
const m = 1 + (AMP[depth] - 1) * breath.value;
|
|
118
|
+
const tx = depth * ENTROPY_MARK_STEP.x * open.value * m + depth * PX * px.value * open.value;
|
|
119
|
+
const ty = depth * ENTROPY_MARK_STEP.y * open.value * m + depth * PY * py.value * open.value;
|
|
120
|
+
return {
|
|
121
|
+
opacity: open.value,
|
|
122
|
+
transform: [{ translateX: tx }, { translateY: ty }],
|
|
123
|
+
};
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
return (
|
|
127
|
+
<Animated.View style={[{ position: "absolute", width, height, pointerEvents: "none" }, style]}>
|
|
128
|
+
<Svg width={width} height={height} viewBox={ENTROPY_MARK_VIEWBOX}>
|
|
129
|
+
<Path d={ENTROPY_MARK_PATH} fillRule="evenodd" fill={fill} />
|
|
130
|
+
</Svg>
|
|
131
|
+
</Animated.View>
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Touch-interactive company `>_` mark — flat at rest, echo-cascade + parallax
|
|
137
|
+
* while pressed, clean collapse on release. The RN twin of the website logo.
|
|
138
|
+
*/
|
|
139
|
+
export function EntropyMarkAnimated({
|
|
140
|
+
size = 28,
|
|
141
|
+
variant = "mono",
|
|
142
|
+
scheme,
|
|
143
|
+
active = false,
|
|
144
|
+
animateOnPress = true,
|
|
145
|
+
}: EntropyMarkAnimatedProps) {
|
|
146
|
+
const { colorScheme } = useColorScheme();
|
|
147
|
+
const p = PALETTE[scheme ?? (colorScheme === "dark" ? "dark" : "light")];
|
|
148
|
+
const width = Math.round(size * ENTROPY_MARK_ASPECT);
|
|
149
|
+
|
|
150
|
+
const open = useSharedValue(active ? 1 : 0);
|
|
151
|
+
const px = useSharedValue(0);
|
|
152
|
+
const py = useSharedValue(0);
|
|
153
|
+
|
|
154
|
+
useEffect(() => {
|
|
155
|
+
open.value = withTiming(active ? 1 : 0, {
|
|
156
|
+
duration: 450,
|
|
157
|
+
easing: Easing.out(Easing.cubic),
|
|
158
|
+
reduceMotion: ReduceMotion.System,
|
|
159
|
+
});
|
|
160
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
161
|
+
}, [active]);
|
|
162
|
+
|
|
163
|
+
const track = (e: GestureResponderEvent) => {
|
|
164
|
+
// Normalize finger position over the mark to -1..1 (parallax input).
|
|
165
|
+
const nx = Math.max(-1, Math.min(1, (e.nativeEvent.locationX / width - 0.5) * 2));
|
|
166
|
+
const ny = Math.max(-1, Math.min(1, (e.nativeEvent.locationY / size - 0.5) * 2));
|
|
167
|
+
px.value = withTiming(nx, { duration: 80, reduceMotion: ReduceMotion.System });
|
|
168
|
+
py.value = withTiming(ny, { duration: 80, reduceMotion: ReduceMotion.System });
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
const press = (down: boolean) => (e: GestureResponderEvent) => {
|
|
172
|
+
if (!animateOnPress) {
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
if (down) {
|
|
176
|
+
track(e);
|
|
177
|
+
open.value = withTiming(1, {
|
|
178
|
+
duration: 450,
|
|
179
|
+
easing: Easing.out(Easing.cubic),
|
|
180
|
+
reduceMotion: ReduceMotion.System,
|
|
181
|
+
});
|
|
182
|
+
} else {
|
|
183
|
+
// Release: echoes resolve back into the source, parallax recenters.
|
|
184
|
+
open.value = withTiming(active ? 1 : 0, {
|
|
185
|
+
duration: 500,
|
|
186
|
+
easing: Easing.inOut(Easing.cubic),
|
|
187
|
+
reduceMotion: ReduceMotion.System,
|
|
188
|
+
});
|
|
189
|
+
px.value = withTiming(0, { duration: 500, reduceMotion: ReduceMotion.System });
|
|
190
|
+
py.value = withTiming(0, { duration: 500, reduceMotion: ReduceMotion.System });
|
|
191
|
+
}
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
const chromaStyle = useAnimatedStyle(() => ({ opacity: open.value }));
|
|
195
|
+
|
|
196
|
+
return (
|
|
197
|
+
<View
|
|
198
|
+
style={{ width, height: size }}
|
|
199
|
+
onStartShouldSetResponder={() => animateOnPress}
|
|
200
|
+
onResponderGrant={press(true)}
|
|
201
|
+
onResponderMove={track}
|
|
202
|
+
onResponderRelease={press(false)}
|
|
203
|
+
onResponderTerminate={press(false)}
|
|
204
|
+
>
|
|
205
|
+
{/* echoes: far (dim) → near, each on its own compositor layer */}
|
|
206
|
+
{([3, 2, 1] as const).map((i) => (
|
|
207
|
+
<Echo
|
|
208
|
+
key={i}
|
|
209
|
+
depth={i}
|
|
210
|
+
fill={p.echo[i]}
|
|
211
|
+
open={open}
|
|
212
|
+
px={px}
|
|
213
|
+
py={py}
|
|
214
|
+
width={width}
|
|
215
|
+
height={size}
|
|
216
|
+
/>
|
|
217
|
+
))}
|
|
218
|
+
|
|
219
|
+
{/* chroma fringe — rides `open` (sharp offset; RN SVG has no cheap blur) */}
|
|
220
|
+
{variant === "chroma" ? (
|
|
221
|
+
<Animated.View
|
|
222
|
+
style={[
|
|
223
|
+
{ position: "absolute", width, height: size, pointerEvents: "none" },
|
|
224
|
+
chromaStyle,
|
|
225
|
+
]}
|
|
226
|
+
>
|
|
227
|
+
<Svg width={width} height={size} viewBox={ENTROPY_MARK_VIEWBOX}>
|
|
228
|
+
<Path
|
|
229
|
+
d={ENTROPY_MARK_PATH}
|
|
230
|
+
fillRule="evenodd"
|
|
231
|
+
fill={p.cyan}
|
|
232
|
+
opacity={0.5}
|
|
233
|
+
transform="translate(10 8)"
|
|
234
|
+
/>
|
|
235
|
+
<Path
|
|
236
|
+
d={ENTROPY_MARK_PATH}
|
|
237
|
+
fillRule="evenodd"
|
|
238
|
+
fill={p.red}
|
|
239
|
+
opacity={0.45}
|
|
240
|
+
transform="translate(-10 -8)"
|
|
241
|
+
/>
|
|
242
|
+
</Svg>
|
|
243
|
+
</Animated.View>
|
|
244
|
+
) : null}
|
|
245
|
+
|
|
246
|
+
{/* sharp source — always visible, never moves (anchored). Absolutely
|
|
247
|
+
positioned + last in the tree so it paints ON TOP of the absolutely-
|
|
248
|
+
positioned echo/chroma layers on web too: CSS paints positioned
|
|
249
|
+
siblings above static ones regardless of DOM order, so a static
|
|
250
|
+
source would otherwise be buried under the echoes on web. */}
|
|
251
|
+
<View style={{ position: "absolute", width, height: size, pointerEvents: "none" }}>
|
|
252
|
+
<Svg width={width} height={size} viewBox={ENTROPY_MARK_VIEWBOX}>
|
|
253
|
+
<Path d={ENTROPY_MARK_PATH} fillRule="evenodd" fill={p.src} />
|
|
254
|
+
</Svg>
|
|
255
|
+
</View>
|
|
256
|
+
</View>
|
|
257
|
+
);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
export default EntropyMarkAnimated;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// Geometry of the Entropy Softworks company mark (`>_`), shared by the static
|
|
2
|
+
// `EntropyMark` and the animated `EntropyMarkAnimated`. Lives in its own module
|
|
3
|
+
// so both can import it without the two components importing each other (which
|
|
4
|
+
// formed a require cycle). Kept in sync with the website
|
|
5
|
+
// (website/src/components/logo.tsx).
|
|
6
|
+
|
|
7
|
+
export const ENTROPY_MARK_VIEWBOX = "300 562 1311 805";
|
|
8
|
+
export const ENTROPY_MARK_ASPECT = 1311 / 805;
|
|
9
|
+
export const ENTROPY_MARK_PATH =
|
|
10
|
+
"M 869,1057.5 L 672,1057.5 L 673,1055.5 L 752.5,1015 L 606.5,941 L 632.5,894 L 633.5,892 L 632,890.5 L 449.5,798 L 449.5,648 L 703,776.5 L 704.5,779 L 679.5,822 L 678,827.5 L 867,923.5 L 869.5,926 L 869,1057.5 Z M 804,1201.5 L 524,1201.5 L 523.5,1194 L 743,1081.5 L 989.5,1082 L 989.5,1106 L 988,1107.5 L 804,1201.5 Z M 1597,1331.5 L 1524,1331.5 L 1354.5,1162 L 1597,1161.5 L 1597,1331.5 Z M 1479,1353.5 L 1011,1353.5 L 1009.5,1352 L 1009.5,1184 L 1310,1183.5 L 1479,1353.5 Z M 404,1344.5 L 404,1225.5 L 635.5,1226 L 404,1344.5 Z";
|
|
11
|
+
export const ENTROPY_MARK_STEP = { x: -30, y: -24 };
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import React, { useEffect } from "react";
|
|
2
|
+
import { View } from "react-native";
|
|
3
|
+
import Svg, { Path } from "react-native-svg";
|
|
4
|
+
import Animated, {
|
|
5
|
+
Easing,
|
|
6
|
+
useAnimatedStyle,
|
|
7
|
+
useSharedValue,
|
|
8
|
+
withRepeat,
|
|
9
|
+
withTiming,
|
|
10
|
+
type SharedValue,
|
|
11
|
+
} from "react-native-reanimated";
|
|
12
|
+
import { useColorScheme } from "nativewind";
|
|
13
|
+
import {
|
|
14
|
+
ENTROPY_MARK_ASPECT,
|
|
15
|
+
ENTROPY_MARK_PATH,
|
|
16
|
+
ENTROPY_MARK_STEP,
|
|
17
|
+
ENTROPY_MARK_VIEWBOX,
|
|
18
|
+
} from "./entropy-mark";
|
|
19
|
+
|
|
20
|
+
// Boot/loading variant of the company mark: instead of all echoes drifting +
|
|
21
|
+
// breathing at once (the website hover), exactly ONE layer is visible at a
|
|
22
|
+
// time. A single pulse travels through the depth layers in sequence — furthest
|
|
23
|
+
// echo → … → sharp source — then loops forever. Each layer sits at its own
|
|
24
|
+
// echo offset (drifted up-left by depth × STEP), so the pulse reads as the mark
|
|
25
|
+
// converging from the deep echoes into the source.
|
|
26
|
+
|
|
27
|
+
interface MarkColors {
|
|
28
|
+
src: string;
|
|
29
|
+
echo: Record<1 | 2 | 3, string>;
|
|
30
|
+
}
|
|
31
|
+
const COLORS: Record<"light" | "dark", MarkColors> = {
|
|
32
|
+
light: { src: "#000000", echo: { 3: "#cbcbcb", 2: "#a3a3a3", 1: "#525252" } },
|
|
33
|
+
dark: { src: "#ffffff", echo: { 3: "#373737", 2: "#5f5f5f", 1: "#8c8c8c" } },
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
// Order the pulse travels: sharp source first → out through the echoes.
|
|
37
|
+
const DEPTHS = [0, 1, 2, 3] as const; // 0 = source
|
|
38
|
+
const COUNT = DEPTHS.length;
|
|
39
|
+
|
|
40
|
+
export interface EntropyMarkSequentialProps {
|
|
41
|
+
/** Rendered height in px. Width follows the ~1.63:1 aspect. */
|
|
42
|
+
size?: number;
|
|
43
|
+
/** Override the theme; defaults to the active color scheme. */
|
|
44
|
+
scheme?: "light" | "dark";
|
|
45
|
+
/** Full-cycle duration in ms (time to sweep through all layers once). */
|
|
46
|
+
durationMs?: number;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function Layer({
|
|
50
|
+
prog,
|
|
51
|
+
index,
|
|
52
|
+
width,
|
|
53
|
+
size,
|
|
54
|
+
color,
|
|
55
|
+
offsetX,
|
|
56
|
+
offsetY,
|
|
57
|
+
}: {
|
|
58
|
+
prog: SharedValue<number>;
|
|
59
|
+
index: number;
|
|
60
|
+
width: number;
|
|
61
|
+
size: number;
|
|
62
|
+
color: string;
|
|
63
|
+
offsetX: number;
|
|
64
|
+
offsetY: number;
|
|
65
|
+
}) {
|
|
66
|
+
const style = useAnimatedStyle(() => {
|
|
67
|
+
// Triangular pulse centered on this layer's slot; near-zero at the
|
|
68
|
+
// neighbours' centers so only one layer is lit at a time. Wraps so the
|
|
69
|
+
// loop has no seam.
|
|
70
|
+
const center = (index + 0.5) / COUNT;
|
|
71
|
+
let d = Math.abs(prog.value - center);
|
|
72
|
+
d = Math.min(d, 1 - d);
|
|
73
|
+
const opacity = Math.max(0, Math.min(1, 1 - d * COUNT * 1.15));
|
|
74
|
+
return { opacity };
|
|
75
|
+
});
|
|
76
|
+
return (
|
|
77
|
+
<Animated.View
|
|
78
|
+
style={[
|
|
79
|
+
{
|
|
80
|
+
position: "absolute",
|
|
81
|
+
width,
|
|
82
|
+
height: size,
|
|
83
|
+
pointerEvents: "none",
|
|
84
|
+
transform: [{ translateX: offsetX }, { translateY: offsetY }],
|
|
85
|
+
},
|
|
86
|
+
style,
|
|
87
|
+
]}
|
|
88
|
+
>
|
|
89
|
+
<Svg width={width} height={size} viewBox={ENTROPY_MARK_VIEWBOX}>
|
|
90
|
+
<Path d={ENTROPY_MARK_PATH} fillRule="evenodd" fill={color} />
|
|
91
|
+
</Svg>
|
|
92
|
+
</Animated.View>
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export function EntropyMarkSequential({
|
|
97
|
+
size = 96,
|
|
98
|
+
scheme,
|
|
99
|
+
durationMs = 1000,
|
|
100
|
+
}: EntropyMarkSequentialProps) {
|
|
101
|
+
const { colorScheme } = useColorScheme();
|
|
102
|
+
const c = COLORS[scheme ?? (colorScheme === "dark" ? "dark" : "light")];
|
|
103
|
+
const width = Math.round(size * ENTROPY_MARK_ASPECT);
|
|
104
|
+
|
|
105
|
+
const prog = useSharedValue(0);
|
|
106
|
+
useEffect(() => {
|
|
107
|
+
prog.value = withRepeat(
|
|
108
|
+
withTiming(1, { duration: durationMs, easing: Easing.linear }),
|
|
109
|
+
-1,
|
|
110
|
+
false
|
|
111
|
+
);
|
|
112
|
+
}, [prog, durationMs]);
|
|
113
|
+
|
|
114
|
+
return (
|
|
115
|
+
<View style={{ width, height: size }}>
|
|
116
|
+
{DEPTHS.map((depth, index) => (
|
|
117
|
+
<Layer
|
|
118
|
+
key={depth}
|
|
119
|
+
prog={prog}
|
|
120
|
+
index={index}
|
|
121
|
+
width={width}
|
|
122
|
+
size={size}
|
|
123
|
+
color={depth === 0 ? c.src : c.echo[depth]}
|
|
124
|
+
offsetX={depth * ENTROPY_MARK_STEP.x}
|
|
125
|
+
offsetY={depth * ENTROPY_MARK_STEP.y}
|
|
126
|
+
/>
|
|
127
|
+
))}
|
|
128
|
+
</View>
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export default EntropyMarkSequential;
|