@proveanything/smartlinks-auth-ui 0.1.5 → 0.1.7

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.
@@ -1 +1 @@
1
- {"version":3,"file":"SmartlinksAuthUI.d.ts","sourceRoot":"","sources":["../../src/components/SmartlinksAuthUI.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAUnD,OAAO,KAAK,EAAE,qBAAqB,EAAyC,MAAM,UAAU,CAAC;AAK7F,eAAO,MAAM,gBAAgB,EAAE,KAAK,CAAC,EAAE,CAAC,qBAAqB,CAu3B5D,CAAC"}
1
+ {"version":3,"file":"SmartlinksAuthUI.d.ts","sourceRoot":"","sources":["../../src/components/SmartlinksAuthUI.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAUnD,OAAO,KAAK,EAAE,qBAAqB,EAAyC,MAAM,UAAU,CAAC;AAkD7F,eAAO,MAAM,gBAAgB,EAAE,KAAK,CAAC,EAAE,CAAC,qBAAqB,CAu5B5D,CAAC"}
package/dist/index.esm.js CHANGED
@@ -11413,10 +11413,52 @@ const useAuth = () => {
11413
11413
 
11414
11414
  // Default Smartlinks Google OAuth Client ID (public - safe to expose)
11415
11415
  const DEFAULT_GOOGLE_CLIENT_ID = '696509063554-jdlbjl8vsjt7cr0vgkjkjf3ffnvi3a70.apps.googleusercontent.com';
11416
- const SmartlinksAuthUI = ({ apiEndpoint, clientId, clientName, accountData, onAuthSuccess, onAuthError, enabledProviders = ['email', 'google', 'phone'], initialMode = 'login', redirectUrl, theme = 'light', className, customization, skipConfigFetch = false, minimal = false, }) => {
11416
+ // Default auth UI configuration when no clientId is provided
11417
+ const DEFAULT_AUTH_CONFIG = {
11418
+ branding: {
11419
+ title: '', // No title by default (minimal)
11420
+ subtitle: 'Sign in to your account',
11421
+ logoUrl: 'https://smartlinks.app/smartlinks/landscape-medium.png',
11422
+ primaryColor: '#3B82F6',
11423
+ secondaryColor: '#1D4ED8',
11424
+ backgroundColor: '#e0f2fe',
11425
+ buttonStyle: 'rounded',
11426
+ fontFamily: 'Inter, sans-serif'
11427
+ },
11428
+ emailDisplayMode: 'button',
11429
+ googleOAuthFlow: 'oneTap'
11430
+ };
11431
+ // Helper to dynamically load Google Identity Services if not already loaded
11432
+ const loadGoogleIdentityServices = () => {
11433
+ return new Promise((resolve, reject) => {
11434
+ // Check if already loaded
11435
+ if (window.google?.accounts) {
11436
+ resolve();
11437
+ return;
11438
+ }
11439
+ // Check if script is already being loaded
11440
+ const existingScript = document.querySelector('script[src="https://accounts.google.com/gsi/client"]');
11441
+ if (existingScript) {
11442
+ // Wait for existing script to load
11443
+ existingScript.addEventListener('load', () => resolve());
11444
+ existingScript.addEventListener('error', () => reject(new Error('Failed to load Google Identity Services')));
11445
+ return;
11446
+ }
11447
+ // Dynamically inject the script
11448
+ const script = document.createElement('script');
11449
+ script.src = 'https://accounts.google.com/gsi/client';
11450
+ script.async = true;
11451
+ script.defer = true;
11452
+ script.onload = () => resolve();
11453
+ script.onerror = () => reject(new Error('Failed to load Google Identity Services'));
11454
+ document.head.appendChild(script);
11455
+ });
11456
+ };
11457
+ const SmartlinksAuthUI = ({ apiEndpoint, clientId, clientName, accountData, onAuthSuccess, onAuthError, enabledProviders = ['email', 'google', 'phone'], initialMode = 'login', redirectUrl, theme = 'auto', className, customization, skipConfigFetch = false, minimal = false, }) => {
11417
11458
  const [mode, setMode] = useState(initialMode);
11418
11459
  const [loading, setLoading] = useState(false);
11419
11460
  const [error, setError] = useState();
11461
+ const [resolvedTheme, setResolvedTheme] = useState('light');
11420
11462
  const [resetSuccess, setResetSuccess] = useState(false);
11421
11463
  const [authSuccess, setAuthSuccess] = useState(false);
11422
11464
  const [successMessage, setSuccessMessage] = useState();
@@ -11430,6 +11472,19 @@ const SmartlinksAuthUI = ({ apiEndpoint, clientId, clientName, accountData, onAu
11430
11472
  const [showEmailForm, setShowEmailForm] = useState(false); // Track if email form should be shown when emailDisplayMode is 'button'
11431
11473
  const api = new AuthAPI(apiEndpoint, clientId, clientName);
11432
11474
  const auth = useAuth();
11475
+ // Dark mode detection and theme management
11476
+ useEffect(() => {
11477
+ if (theme !== 'auto') {
11478
+ setResolvedTheme(theme);
11479
+ return;
11480
+ }
11481
+ // Auto-detect system theme preference
11482
+ const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
11483
+ const updateTheme = () => setResolvedTheme(mediaQuery.matches ? 'dark' : 'light');
11484
+ updateTheme();
11485
+ mediaQuery.addEventListener('change', updateTheme);
11486
+ return () => mediaQuery.removeEventListener('change', updateTheme);
11487
+ }, [theme]);
11433
11488
  // Reinitialize Smartlinks SDK when apiEndpoint changes (for test/dev scenarios)
11434
11489
  // IMPORTANT: Preserve bearer token during reinitialization
11435
11490
  useEffect(() => {
@@ -11468,9 +11523,19 @@ const SmartlinksAuthUI = ({ apiEndpoint, clientId, clientName, accountData, onAu
11468
11523
  return;
11469
11524
  }
11470
11525
  const fetchConfig = async () => {
11526
+ // If no clientId provided, use default config immediately without API call
11527
+ if (!clientId) {
11528
+ const defaultConfig = {
11529
+ ...DEFAULT_AUTH_CONFIG,
11530
+ enabledProviders: enabledProviders || ['email', 'google', 'phone']
11531
+ };
11532
+ setConfig({ ...defaultConfig, ...customization });
11533
+ setConfigLoading(false);
11534
+ return;
11535
+ }
11471
11536
  try {
11472
11537
  // Check localStorage cache first
11473
- const cacheKey = `auth_ui_config_${clientId || 'default'}`;
11538
+ const cacheKey = `auth_ui_config_${clientId}`;
11474
11539
  const cached = localStorage.getItem(cacheKey);
11475
11540
  if (cached) {
11476
11541
  const { config: cachedConfig, timestamp } = JSON.parse(cached);
@@ -11788,9 +11853,11 @@ const SmartlinksAuthUI = ({ apiEndpoint, clientId, clientName, accountData, onAu
11788
11853
  setLoading(true);
11789
11854
  setError(undefined);
11790
11855
  try {
11856
+ // Dynamically load Google Identity Services if not already loaded
11857
+ await loadGoogleIdentityServices();
11791
11858
  const google = window.google;
11792
- if (!google) {
11793
- throw new Error('Google Identity Services not loaded. Please check your internet connection.');
11859
+ if (!google?.accounts) {
11860
+ throw new Error('Google Identity Services failed to initialize');
11794
11861
  }
11795
11862
  if (oauthFlow === 'popup') {
11796
11863
  // Use OAuth2 popup flow (works in iframes but requires popup permission)
@@ -11960,9 +12027,9 @@ const SmartlinksAuthUI = ({ apiEndpoint, clientId, clientName, accountData, onAu
11960
12027
  }
11961
12028
  };
11962
12029
  if (configLoading) {
11963
- return (jsx(AuthContainer, { theme: theme, className: className, minimal: minimal || config?.branding?.minimal || false, children: jsx("div", { style: { textAlign: 'center', padding: '2rem' }, children: jsx("div", { className: "auth-spinner" }) }) }));
12030
+ return (jsx(AuthContainer, { theme: resolvedTheme, className: className, minimal: minimal || config?.branding?.minimal || false, children: jsx("div", { style: { textAlign: 'center', padding: '2rem' }, children: jsx("div", { className: "auth-spinner" }) }) }));
11964
12031
  }
11965
- return (jsx(AuthContainer, { theme: theme, className: className, config: config, minimal: minimal || config?.branding?.minimal || false, children: authSuccess ? (jsxs("div", { style: { textAlign: 'center', padding: '2rem' }, children: [jsx("div", { style: {
12032
+ return (jsx(AuthContainer, { theme: resolvedTheme, className: className, config: config, minimal: minimal || config?.branding?.minimal || false, children: authSuccess ? (jsxs("div", { style: { textAlign: 'center', padding: '2rem' }, children: [jsx("div", { style: {
11966
12033
  color: 'var(--auth-primary-color, #4F46E5)',
11967
12034
  fontSize: '3rem',
11968
12035
  marginBottom: '1rem'