@authon/react 0.1.19 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -26,6 +26,8 @@ __export(index_exports, {
26
26
  SignUp: () => SignUp,
27
27
  SignedIn: () => SignedIn,
28
28
  SignedOut: () => SignedOut,
29
+ SocialButton: () => SocialButton,
30
+ SocialButtons: () => SocialButtons,
29
31
  UserButton: () => UserButton,
30
32
  useAuthon: () => useAuthon,
31
33
  useUser: () => useUser
@@ -299,6 +301,188 @@ function Protect({ children, fallback = null, condition }) {
299
301
  if (condition && !condition(user)) return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_jsx_runtime7.Fragment, { children: fallback });
300
302
  return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_jsx_runtime7.Fragment, { children });
301
303
  }
304
+
305
+ // src/SocialButton.tsx
306
+ var import_shared = require("@authon/shared");
307
+ var import_js2 = require("@authon/js");
308
+ var import_jsx_runtime8 = require("react/jsx-runtime");
309
+ var baseStyle = {
310
+ display: "flex",
311
+ alignItems: "center",
312
+ justifyContent: "center",
313
+ gap: 10,
314
+ paddingLeft: 16,
315
+ paddingRight: 16,
316
+ border: "none",
317
+ cursor: "pointer",
318
+ fontFamily: "inherit",
319
+ transition: "opacity 0.15s",
320
+ width: "100%"
321
+ };
322
+ var compactBaseStyle = {
323
+ display: "flex",
324
+ alignItems: "center",
325
+ justifyContent: "center",
326
+ border: "none",
327
+ cursor: "pointer",
328
+ transition: "opacity 0.15s",
329
+ padding: 0
330
+ };
331
+ function SocialButton({
332
+ provider,
333
+ onClick,
334
+ loading = false,
335
+ disabled = false,
336
+ label,
337
+ compact = false,
338
+ className,
339
+ style: userStyle,
340
+ iconSize,
341
+ borderRadius = 10,
342
+ height = 48,
343
+ size = 48
344
+ }) {
345
+ const colors = import_shared.PROVIDER_COLORS[provider] || { bg: "#333", text: "#fff" };
346
+ const displayName = import_shared.PROVIDER_DISPLAY_NAMES[provider] || provider;
347
+ const buttonLabel = label ?? `Continue with ${displayName}`;
348
+ const needsBorder = colors.bg.toLowerCase() === "#ffffff";
349
+ const resolvedIconSize = iconSize ?? (compact ? 24 : 20);
350
+ const config = (0, import_js2.getProviderButtonConfig)(provider);
351
+ const iconSvg = config.iconSvg.replace(/width="\d+"/, `width="${resolvedIconSize}"`).replace(/height="\d+"/, `height="${resolvedIconSize}"`);
352
+ const borderProps = needsBorder ? { border: "1px solid #dadce0" } : {};
353
+ if (compact) {
354
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
355
+ "button",
356
+ {
357
+ className,
358
+ style: {
359
+ ...compactBaseStyle,
360
+ backgroundColor: colors.bg,
361
+ borderRadius,
362
+ width: size,
363
+ height: size,
364
+ ...borderProps,
365
+ ...userStyle
366
+ },
367
+ onClick: () => onClick(provider),
368
+ disabled: disabled || loading,
369
+ "aria-label": `Sign in with ${displayName}`,
370
+ children: loading ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
371
+ "span",
372
+ {
373
+ style: {
374
+ display: "inline-block",
375
+ width: 16,
376
+ height: 16,
377
+ border: `2px solid ${colors.text}`,
378
+ borderTopColor: "transparent",
379
+ borderRadius: "50%",
380
+ animation: "authon-spin 0.6s linear infinite"
381
+ }
382
+ }
383
+ ) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
384
+ "span",
385
+ {
386
+ style: { display: "flex", alignItems: "center", flexShrink: 0 },
387
+ dangerouslySetInnerHTML: { __html: iconSvg }
388
+ }
389
+ )
390
+ }
391
+ );
392
+ }
393
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
394
+ "button",
395
+ {
396
+ className,
397
+ style: {
398
+ ...baseStyle,
399
+ backgroundColor: colors.bg,
400
+ color: colors.text,
401
+ borderRadius,
402
+ height,
403
+ ...borderProps,
404
+ ...userStyle
405
+ },
406
+ onClick: () => onClick(provider),
407
+ disabled: disabled || loading,
408
+ "aria-label": `Sign in with ${displayName}`,
409
+ children: loading ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
410
+ "span",
411
+ {
412
+ style: {
413
+ display: "inline-block",
414
+ width: 16,
415
+ height: 16,
416
+ border: `2px solid ${colors.text}`,
417
+ borderTopColor: "transparent",
418
+ borderRadius: "50%",
419
+ animation: "authon-spin 0.6s linear infinite"
420
+ }
421
+ }
422
+ ) : /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
423
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
424
+ "span",
425
+ {
426
+ style: { display: "flex", alignItems: "center", flexShrink: 0 },
427
+ dangerouslySetInnerHTML: { __html: iconSvg }
428
+ }
429
+ ),
430
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { style: { fontSize: 15, fontWeight: 600, whiteSpace: "nowrap" }, children: buttonLabel })
431
+ ] })
432
+ }
433
+ );
434
+ }
435
+
436
+ // src/SocialButtons.tsx
437
+ var import_react6 = require("react");
438
+ var import_jsx_runtime9 = require("react/jsx-runtime");
439
+ function SocialButtons({
440
+ onSuccess,
441
+ onError,
442
+ className,
443
+ style: userStyle,
444
+ gap,
445
+ compact = false,
446
+ labels,
447
+ buttonProps
448
+ }) {
449
+ const { client } = useAuthon();
450
+ const [providers, setProviders] = (0, import_react6.useState)([]);
451
+ const [loadingProvider, setLoadingProvider] = (0, import_react6.useState)(null);
452
+ (0, import_react6.useEffect)(() => {
453
+ if (!client) return;
454
+ client.getProviders().then((p) => setProviders(p));
455
+ }, [client]);
456
+ if (providers.length === 0) return null;
457
+ const resolvedGap = gap ?? (compact ? 12 : 10);
458
+ const handleClick = async (provider) => {
459
+ if (!client) return;
460
+ setLoadingProvider(provider);
461
+ try {
462
+ await client.signInWithOAuth(provider);
463
+ onSuccess?.();
464
+ } catch (e) {
465
+ const error = e instanceof Error ? e : new Error(String(e));
466
+ onError?.(error);
467
+ } finally {
468
+ setLoadingProvider(null);
469
+ }
470
+ };
471
+ const containerStyle = compact ? { display: "flex", flexDirection: "row", flexWrap: "wrap", justifyContent: "center", gap: resolvedGap, ...userStyle } : { display: "flex", flexDirection: "column", gap: resolvedGap, ...userStyle };
472
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className, style: containerStyle, children: providers.map((provider) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
473
+ SocialButton,
474
+ {
475
+ provider,
476
+ onClick: handleClick,
477
+ loading: loadingProvider === provider,
478
+ disabled: !!loadingProvider,
479
+ compact,
480
+ label: labels?.[provider],
481
+ ...buttonProps
482
+ },
483
+ provider
484
+ )) });
485
+ }
302
486
  // Annotate the CommonJS export names for ESM import in node:
303
487
  0 && (module.exports = {
304
488
  AuthonProvider,
@@ -307,6 +491,8 @@ function Protect({ children, fallback = null, condition }) {
307
491
  SignUp,
308
492
  SignedIn,
309
493
  SignedOut,
494
+ SocialButton,
495
+ SocialButtons,
310
496
  UserButton,
311
497
  useAuthon,
312
498
  useUser
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/AuthonProvider.tsx","../src/useAuthon.ts","../src/useUser.ts","../src/SignIn.tsx","../src/SignUp.tsx","../src/UserButton.tsx","../src/SignedIn.tsx","../src/SignedOut.tsx","../src/Protect.tsx"],"sourcesContent":["export { AuthonProvider } from './AuthonProvider';\nexport type { AuthonContextValue } from './AuthonProvider';\nexport { useAuthon } from './useAuthon';\nexport { useUser } from './useUser';\nexport { SignIn } from './SignIn';\nexport { SignUp } from './SignUp';\nexport { UserButton } from './UserButton';\nexport { SignedIn } from './SignedIn';\nexport { SignedOut } from './SignedOut';\nexport { Protect } from './Protect';\n","import { createContext, useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport type { ReactNode } from 'react';\nimport { Authon } from '@authon/js';\nimport type { AuthonConfig } from '@authon/js';\nimport type { AuthonUser } from '@authon/shared';\n\nexport interface AuthonContextValue {\n isSignedIn: boolean;\n isLoading: boolean;\n user: AuthonUser | null;\n signOut: () => Promise<void>;\n openSignIn: () => Promise<void>;\n openSignUp: () => Promise<void>;\n getToken: () => string | null;\n client: Authon | null;\n}\n\nexport const AuthonContext = createContext<AuthonContextValue | null>(null);\n\ninterface AuthonProviderProps {\n publishableKey: string;\n children: ReactNode;\n config?: Omit<AuthonConfig, 'mode'>;\n}\n\nexport function AuthonProvider({ publishableKey, children, config }: AuthonProviderProps) {\n const [user, setUser] = useState<AuthonUser | null>(null);\n const [isLoading, setIsLoading] = useState(true);\n const clientRef = useRef<Authon | null>(null);\n\n useEffect(() => {\n const client = new Authon(publishableKey, config);\n clientRef.current = client;\n\n client.on('signedIn', (u) => {\n setUser(u as AuthonUser);\n setIsLoading(false);\n });\n\n client.on('signedOut', () => {\n setUser(null);\n });\n\n client.on('error', () => {\n setIsLoading(false);\n });\n\n const existingUser = client.getUser();\n if (existingUser) {\n setUser(existingUser);\n }\n setIsLoading(false);\n\n return () => {\n client.destroy();\n clientRef.current = null;\n };\n }, [publishableKey]);\n\n const signOut = useCallback(async () => {\n await clientRef.current?.signOut();\n setUser(null);\n }, []);\n\n const openSignIn = useCallback(async () => {\n await clientRef.current?.openSignIn();\n }, []);\n\n const openSignUp = useCallback(async () => {\n await clientRef.current?.openSignUp();\n }, []);\n\n const getToken = useCallback(() => {\n return clientRef.current?.getToken() ?? null;\n }, []);\n\n const value = useMemo<AuthonContextValue>(\n () => ({\n isSignedIn: !!user,\n isLoading,\n user,\n signOut,\n openSignIn,\n openSignUp,\n getToken,\n client: clientRef.current,\n }),\n [user, isLoading, signOut, openSignIn, openSignUp, getToken],\n );\n\n return <AuthonContext.Provider value={value}>{children}</AuthonContext.Provider>;\n}\n","import { useContext } from 'react';\nimport { AuthonContext } from './AuthonProvider';\nimport type { AuthonContextValue } from './AuthonProvider';\n\nexport function useAuthon(): AuthonContextValue {\n const ctx = useContext(AuthonContext);\n if (!ctx) {\n throw new Error('useAuthon must be used within an <AuthonProvider>');\n }\n return ctx;\n}\n","import type { AuthonUser } from '@authon/shared';\nimport { useAuthon } from './useAuthon';\n\nexport function useUser(): { user: AuthonUser | null; isLoading: boolean } {\n const { user, isLoading } = useAuthon();\n return { user, isLoading };\n}\n","import { useEffect, useRef } from 'react';\nimport { useAuthon } from './useAuthon';\n\ninterface SignInProps {\n mode?: 'popup' | 'embedded';\n redirectUrl?: string;\n}\n\nexport function SignIn({ mode = 'popup' }: SignInProps) {\n const { client } = useAuthon();\n const containerRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (mode === 'popup') {\n client?.openSignIn();\n }\n }, [client, mode]);\n\n if (mode === 'embedded') {\n return <div ref={containerRef} id=\"authon-signin-container\" />;\n }\n\n return null;\n}\n","import { useEffect } from 'react';\nimport { useAuthon } from './useAuthon';\n\ninterface SignUpProps {\n mode?: 'popup' | 'embedded';\n}\n\nexport function SignUp({ mode = 'popup' }: SignUpProps) {\n const { client } = useAuthon();\n\n useEffect(() => {\n if (mode === 'popup') {\n client?.openSignUp();\n }\n }, [client, mode]);\n\n if (mode === 'embedded') {\n return <div id=\"authon-signup-container\" />;\n }\n\n return null;\n}\n","import { useCallback, useEffect, useRef, useState } from 'react';\nimport { useAuthon } from './useAuthon';\n\nexport function UserButton() {\n const { user, signOut, openSignIn, isSignedIn } = useAuthon();\n const [open, setOpen] = useState(false);\n const dropdownRef = useRef<HTMLDivElement>(null);\n\n const handleClickOutside = useCallback((e: MouseEvent) => {\n if (dropdownRef.current && !dropdownRef.current.contains(e.target as Node)) {\n setOpen(false);\n }\n }, []);\n\n useEffect(() => {\n if (open) {\n document.addEventListener('mousedown', handleClickOutside);\n }\n return () => document.removeEventListener('mousedown', handleClickOutside);\n }, [open, handleClickOutside]);\n\n if (!isSignedIn) {\n return (\n <button\n onClick={() => openSignIn()}\n style={{\n padding: '8px 16px',\n borderRadius: '8px',\n border: 'none',\n background: 'linear-gradient(135deg, #7c3aed, #4f46e5)',\n color: '#fff',\n cursor: 'pointer',\n fontSize: '14px',\n fontWeight: 600,\n }}\n >\n Sign In\n </button>\n );\n }\n\n const initials = user?.displayName\n ? user.displayName\n .split(' ')\n .map((n) => n[0])\n .join('')\n .toUpperCase()\n .slice(0, 2)\n : (user?.email?.[0] ?? '?').toUpperCase();\n\n return (\n <div ref={dropdownRef} style={{ position: 'relative', display: 'inline-block' }}>\n <button\n onClick={() => setOpen((v) => !v)}\n style={{\n width: '36px',\n height: '36px',\n borderRadius: '50%',\n border: '2px solid #7c3aed',\n background: user?.avatarUrl ? 'transparent' : 'linear-gradient(135deg, #7c3aed, #4f46e5)',\n cursor: 'pointer',\n padding: 0,\n overflow: 'hidden',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n color: '#fff',\n fontSize: '13px',\n fontWeight: 700,\n }}\n >\n {user?.avatarUrl ? (\n <img\n src={user.avatarUrl}\n alt={user.displayName ?? 'avatar'}\n style={{ width: '100%', height: '100%', objectFit: 'cover' }}\n />\n ) : (\n initials\n )}\n </button>\n\n {open && (\n <div\n style={{\n position: 'absolute',\n right: 0,\n top: '44px',\n minWidth: '200px',\n background: '#fff',\n border: '1px solid #e5e7eb',\n borderRadius: '12px',\n boxShadow: '0 8px 24px rgba(0,0,0,0.12)',\n zIndex: 9999,\n overflow: 'hidden',\n }}\n >\n <div\n style={{\n padding: '12px 16px',\n borderBottom: '1px solid #f3f4f6',\n }}\n >\n {user?.displayName && (\n <div style={{ fontSize: '14px', fontWeight: 600, color: '#111827' }}>\n {user.displayName}\n </div>\n )}\n {user?.email && (\n <div style={{ fontSize: '12px', color: '#6b7280', marginTop: '2px' }}>\n {user.email}\n </div>\n )}\n </div>\n\n <button\n onClick={async () => {\n setOpen(false);\n await signOut();\n }}\n style={{\n display: 'block',\n width: '100%',\n padding: '10px 16px',\n textAlign: 'left',\n background: 'none',\n border: 'none',\n cursor: 'pointer',\n fontSize: '14px',\n color: '#ef4444',\n fontWeight: 500,\n }}\n onMouseEnter={(e) => {\n (e.currentTarget as HTMLButtonElement).style.background = '#fef2f2';\n }}\n onMouseLeave={(e) => {\n (e.currentTarget as HTMLButtonElement).style.background = 'none';\n }}\n >\n Sign out\n </button>\n </div>\n )}\n </div>\n );\n}\n","import type { ReactNode } from 'react';\nimport { useAuthon } from './useAuthon';\n\ninterface SignedInProps {\n children: ReactNode;\n}\n\nexport function SignedIn({ children }: SignedInProps) {\n const { isSignedIn, isLoading } = useAuthon();\n if (isLoading || !isSignedIn) return null;\n return <>{children}</>;\n}\n","import type { ReactNode } from 'react';\nimport { useAuthon } from './useAuthon';\n\ninterface SignedOutProps {\n children: ReactNode;\n}\n\nexport function SignedOut({ children }: SignedOutProps) {\n const { isSignedIn, isLoading } = useAuthon();\n if (isLoading || isSignedIn) return null;\n return <>{children}</>;\n}\n","import type { ReactNode } from 'react';\nimport type { AuthonUser } from '@authon/shared';\nimport { useAuthon } from './useAuthon';\n\ninterface ProtectProps {\n children: ReactNode;\n fallback?: ReactNode;\n condition?: (user: AuthonUser) => boolean;\n}\n\nexport function Protect({ children, fallback = null, condition }: ProtectProps) {\n const { isSignedIn, isLoading, user } = useAuthon();\n\n if (isLoading) return null;\n if (!isSignedIn || !user) return <>{fallback}</>;\n if (condition && !condition(user)) return <>{fallback}</>;\n\n return <>{children}</>;\n}\n"],"mappings":"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","names":["import_react","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/AuthonProvider.tsx","../src/useAuthon.ts","../src/useUser.ts","../src/SignIn.tsx","../src/SignUp.tsx","../src/UserButton.tsx","../src/SignedIn.tsx","../src/SignedOut.tsx","../src/Protect.tsx","../src/SocialButton.tsx","../src/SocialButtons.tsx"],"sourcesContent":["export { AuthonProvider } from './AuthonProvider';\nexport type { AuthonContextValue } from './AuthonProvider';\nexport { useAuthon } from './useAuthon';\nexport { useUser } from './useUser';\nexport { SignIn } from './SignIn';\nexport { SignUp } from './SignUp';\nexport { UserButton } from './UserButton';\nexport { SignedIn } from './SignedIn';\nexport { SignedOut } from './SignedOut';\nexport { Protect } from './Protect';\nexport { SocialButton } from './SocialButton';\nexport type { SocialButtonProps } from './SocialButton';\nexport { SocialButtons } from './SocialButtons';\nexport type { SocialButtonsProps } from './SocialButtons';\n","import { createContext, useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport type { ReactNode } from 'react';\nimport { Authon } from '@authon/js';\nimport type { AuthonConfig } from '@authon/js';\nimport type { AuthonUser } from '@authon/shared';\n\nexport interface AuthonContextValue {\n isSignedIn: boolean;\n isLoading: boolean;\n user: AuthonUser | null;\n signOut: () => Promise<void>;\n openSignIn: () => Promise<void>;\n openSignUp: () => Promise<void>;\n getToken: () => string | null;\n client: Authon | null;\n}\n\nexport const AuthonContext = createContext<AuthonContextValue | null>(null);\n\ninterface AuthonProviderProps {\n publishableKey: string;\n children: ReactNode;\n config?: Omit<AuthonConfig, 'mode'>;\n}\n\nexport function AuthonProvider({ publishableKey, children, config }: AuthonProviderProps) {\n const [user, setUser] = useState<AuthonUser | null>(null);\n const [isLoading, setIsLoading] = useState(true);\n const clientRef = useRef<Authon | null>(null);\n\n useEffect(() => {\n const client = new Authon(publishableKey, config);\n clientRef.current = client;\n\n client.on('signedIn', (u) => {\n setUser(u as AuthonUser);\n setIsLoading(false);\n });\n\n client.on('signedOut', () => {\n setUser(null);\n });\n\n client.on('error', () => {\n setIsLoading(false);\n });\n\n const existingUser = client.getUser();\n if (existingUser) {\n setUser(existingUser);\n }\n setIsLoading(false);\n\n return () => {\n client.destroy();\n clientRef.current = null;\n };\n }, [publishableKey]);\n\n const signOut = useCallback(async () => {\n await clientRef.current?.signOut();\n setUser(null);\n }, []);\n\n const openSignIn = useCallback(async () => {\n await clientRef.current?.openSignIn();\n }, []);\n\n const openSignUp = useCallback(async () => {\n await clientRef.current?.openSignUp();\n }, []);\n\n const getToken = useCallback(() => {\n return clientRef.current?.getToken() ?? null;\n }, []);\n\n const value = useMemo<AuthonContextValue>(\n () => ({\n isSignedIn: !!user,\n isLoading,\n user,\n signOut,\n openSignIn,\n openSignUp,\n getToken,\n client: clientRef.current,\n }),\n [user, isLoading, signOut, openSignIn, openSignUp, getToken],\n );\n\n return <AuthonContext.Provider value={value}>{children}</AuthonContext.Provider>;\n}\n","import { useContext } from 'react';\nimport { AuthonContext } from './AuthonProvider';\nimport type { AuthonContextValue } from './AuthonProvider';\n\nexport function useAuthon(): AuthonContextValue {\n const ctx = useContext(AuthonContext);\n if (!ctx) {\n throw new Error('useAuthon must be used within an <AuthonProvider>');\n }\n return ctx;\n}\n","import type { AuthonUser } from '@authon/shared';\nimport { useAuthon } from './useAuthon';\n\nexport function useUser(): { user: AuthonUser | null; isLoading: boolean } {\n const { user, isLoading } = useAuthon();\n return { user, isLoading };\n}\n","import { useEffect, useRef } from 'react';\nimport { useAuthon } from './useAuthon';\n\ninterface SignInProps {\n mode?: 'popup' | 'embedded';\n redirectUrl?: string;\n}\n\nexport function SignIn({ mode = 'popup' }: SignInProps) {\n const { client } = useAuthon();\n const containerRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (mode === 'popup') {\n client?.openSignIn();\n }\n }, [client, mode]);\n\n if (mode === 'embedded') {\n return <div ref={containerRef} id=\"authon-signin-container\" />;\n }\n\n return null;\n}\n","import { useEffect } from 'react';\nimport { useAuthon } from './useAuthon';\n\ninterface SignUpProps {\n mode?: 'popup' | 'embedded';\n}\n\nexport function SignUp({ mode = 'popup' }: SignUpProps) {\n const { client } = useAuthon();\n\n useEffect(() => {\n if (mode === 'popup') {\n client?.openSignUp();\n }\n }, [client, mode]);\n\n if (mode === 'embedded') {\n return <div id=\"authon-signup-container\" />;\n }\n\n return null;\n}\n","import { useCallback, useEffect, useRef, useState } from 'react';\nimport { useAuthon } from './useAuthon';\n\nexport function UserButton() {\n const { user, signOut, openSignIn, isSignedIn } = useAuthon();\n const [open, setOpen] = useState(false);\n const dropdownRef = useRef<HTMLDivElement>(null);\n\n const handleClickOutside = useCallback((e: MouseEvent) => {\n if (dropdownRef.current && !dropdownRef.current.contains(e.target as Node)) {\n setOpen(false);\n }\n }, []);\n\n useEffect(() => {\n if (open) {\n document.addEventListener('mousedown', handleClickOutside);\n }\n return () => document.removeEventListener('mousedown', handleClickOutside);\n }, [open, handleClickOutside]);\n\n if (!isSignedIn) {\n return (\n <button\n onClick={() => openSignIn()}\n style={{\n padding: '8px 16px',\n borderRadius: '8px',\n border: 'none',\n background: 'linear-gradient(135deg, #7c3aed, #4f46e5)',\n color: '#fff',\n cursor: 'pointer',\n fontSize: '14px',\n fontWeight: 600,\n }}\n >\n Sign In\n </button>\n );\n }\n\n const initials = user?.displayName\n ? user.displayName\n .split(' ')\n .map((n) => n[0])\n .join('')\n .toUpperCase()\n .slice(0, 2)\n : (user?.email?.[0] ?? '?').toUpperCase();\n\n return (\n <div ref={dropdownRef} style={{ position: 'relative', display: 'inline-block' }}>\n <button\n onClick={() => setOpen((v) => !v)}\n style={{\n width: '36px',\n height: '36px',\n borderRadius: '50%',\n border: '2px solid #7c3aed',\n background: user?.avatarUrl ? 'transparent' : 'linear-gradient(135deg, #7c3aed, #4f46e5)',\n cursor: 'pointer',\n padding: 0,\n overflow: 'hidden',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n color: '#fff',\n fontSize: '13px',\n fontWeight: 700,\n }}\n >\n {user?.avatarUrl ? (\n <img\n src={user.avatarUrl}\n alt={user.displayName ?? 'avatar'}\n style={{ width: '100%', height: '100%', objectFit: 'cover' }}\n />\n ) : (\n initials\n )}\n </button>\n\n {open && (\n <div\n style={{\n position: 'absolute',\n right: 0,\n top: '44px',\n minWidth: '200px',\n background: '#fff',\n border: '1px solid #e5e7eb',\n borderRadius: '12px',\n boxShadow: '0 8px 24px rgba(0,0,0,0.12)',\n zIndex: 9999,\n overflow: 'hidden',\n }}\n >\n <div\n style={{\n padding: '12px 16px',\n borderBottom: '1px solid #f3f4f6',\n }}\n >\n {user?.displayName && (\n <div style={{ fontSize: '14px', fontWeight: 600, color: '#111827' }}>\n {user.displayName}\n </div>\n )}\n {user?.email && (\n <div style={{ fontSize: '12px', color: '#6b7280', marginTop: '2px' }}>\n {user.email}\n </div>\n )}\n </div>\n\n <button\n onClick={async () => {\n setOpen(false);\n await signOut();\n }}\n style={{\n display: 'block',\n width: '100%',\n padding: '10px 16px',\n textAlign: 'left',\n background: 'none',\n border: 'none',\n cursor: 'pointer',\n fontSize: '14px',\n color: '#ef4444',\n fontWeight: 500,\n }}\n onMouseEnter={(e) => {\n (e.currentTarget as HTMLButtonElement).style.background = '#fef2f2';\n }}\n onMouseLeave={(e) => {\n (e.currentTarget as HTMLButtonElement).style.background = 'none';\n }}\n >\n Sign out\n </button>\n </div>\n )}\n </div>\n );\n}\n","import type { ReactNode } from 'react';\nimport { useAuthon } from './useAuthon';\n\ninterface SignedInProps {\n children: ReactNode;\n}\n\nexport function SignedIn({ children }: SignedInProps) {\n const { isSignedIn, isLoading } = useAuthon();\n if (isLoading || !isSignedIn) return null;\n return <>{children}</>;\n}\n","import type { ReactNode } from 'react';\nimport { useAuthon } from './useAuthon';\n\ninterface SignedOutProps {\n children: ReactNode;\n}\n\nexport function SignedOut({ children }: SignedOutProps) {\n const { isSignedIn, isLoading } = useAuthon();\n if (isLoading || isSignedIn) return null;\n return <>{children}</>;\n}\n","import type { ReactNode } from 'react';\nimport type { AuthonUser } from '@authon/shared';\nimport { useAuthon } from './useAuthon';\n\ninterface ProtectProps {\n children: ReactNode;\n fallback?: ReactNode;\n condition?: (user: AuthonUser) => boolean;\n}\n\nexport function Protect({ children, fallback = null, condition }: ProtectProps) {\n const { isSignedIn, isLoading, user } = useAuthon();\n\n if (isLoading) return null;\n if (!isSignedIn || !user) return <>{fallback}</>;\n if (condition && !condition(user)) return <>{fallback}</>;\n\n return <>{children}</>;\n}\n","import { PROVIDER_COLORS, PROVIDER_DISPLAY_NAMES, type OAuthProviderType } from '@authon/shared';\nimport { getProviderButtonConfig } from '@authon/js';\n\nexport interface SocialButtonProps {\n provider: OAuthProviderType;\n onClick: (provider: OAuthProviderType) => void | Promise<void>;\n loading?: boolean;\n disabled?: boolean;\n /** Override button label. Default: \"Continue with {Provider}\" */\n label?: string;\n /** Compact mode — icon-only square button (default: false) */\n compact?: boolean;\n /** Override button className */\n className?: string;\n /** Override button style */\n style?: React.CSSProperties;\n /** Icon size (default: 20, compact default: 24) */\n iconSize?: number;\n /** Border radius in px (default: 10) */\n borderRadius?: number;\n /** Button height in px (default: 48) */\n height?: number;\n /** Button size for compact mode in px (default: 48) */\n size?: number;\n}\n\nconst baseStyle: React.CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n gap: 10,\n paddingLeft: 16,\n paddingRight: 16,\n border: 'none',\n cursor: 'pointer',\n fontFamily: 'inherit',\n transition: 'opacity 0.15s',\n width: '100%',\n};\n\nconst compactBaseStyle: React.CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n border: 'none',\n cursor: 'pointer',\n transition: 'opacity 0.15s',\n padding: 0,\n};\n\nexport function SocialButton({\n provider,\n onClick,\n loading = false,\n disabled = false,\n label,\n compact = false,\n className,\n style: userStyle,\n iconSize,\n borderRadius = 10,\n height = 48,\n size = 48,\n}: SocialButtonProps) {\n const colors = PROVIDER_COLORS[provider] || { bg: '#333', text: '#fff' };\n const displayName = PROVIDER_DISPLAY_NAMES[provider] || provider;\n const buttonLabel = label ?? `Continue with ${displayName}`;\n const needsBorder = colors.bg.toLowerCase() === '#ffffff';\n const resolvedIconSize = iconSize ?? (compact ? 24 : 20);\n const config = getProviderButtonConfig(provider);\n const iconSvg = config.iconSvg.replace(/width=\"\\d+\"/, `width=\"${resolvedIconSize}\"`).replace(/height=\"\\d+\"/, `height=\"${resolvedIconSize}\"`);\n\n const borderProps = needsBorder\n ? { border: '1px solid #dadce0' }\n : {};\n\n if (compact) {\n return (\n <button\n className={className}\n style={{\n ...compactBaseStyle,\n backgroundColor: colors.bg,\n borderRadius,\n width: size,\n height: size,\n ...borderProps,\n ...userStyle,\n }}\n onClick={() => onClick(provider)}\n disabled={disabled || loading}\n aria-label={`Sign in with ${displayName}`}\n >\n {loading ? (\n <span\n style={{\n display: 'inline-block',\n width: 16,\n height: 16,\n border: `2px solid ${colors.text}`,\n borderTopColor: 'transparent',\n borderRadius: '50%',\n animation: 'authon-spin 0.6s linear infinite',\n }}\n />\n ) : (\n <span\n style={{ display: 'flex', alignItems: 'center', flexShrink: 0 }}\n dangerouslySetInnerHTML={{ __html: iconSvg }}\n />\n )}\n </button>\n );\n }\n\n return (\n <button\n className={className}\n style={{\n ...baseStyle,\n backgroundColor: colors.bg,\n color: colors.text,\n borderRadius,\n height,\n ...borderProps,\n ...userStyle,\n }}\n onClick={() => onClick(provider)}\n disabled={disabled || loading}\n aria-label={`Sign in with ${displayName}`}\n >\n {loading ? (\n <span\n style={{\n display: 'inline-block',\n width: 16,\n height: 16,\n border: `2px solid ${colors.text}`,\n borderTopColor: 'transparent',\n borderRadius: '50%',\n animation: 'authon-spin 0.6s linear infinite',\n }}\n />\n ) : (\n <>\n <span\n style={{ display: 'flex', alignItems: 'center', flexShrink: 0 }}\n dangerouslySetInnerHTML={{ __html: iconSvg }}\n />\n <span style={{ fontSize: 15, fontWeight: 600, whiteSpace: 'nowrap' }}>\n {buttonLabel}\n </span>\n </>\n )}\n </button>\n );\n}\n","import { useState, useEffect } from 'react';\nimport type { OAuthProviderType } from '@authon/shared';\nimport { useAuthon } from './useAuthon';\nimport { SocialButton } from './SocialButton';\nimport type { SocialButtonProps } from './SocialButton';\n\nexport interface SocialButtonsProps {\n /** Called after successful OAuth sign-in */\n onSuccess?: () => void;\n /** Called on OAuth error */\n onError?: (error: Error) => void;\n /** Container className */\n className?: string;\n /** Container style */\n style?: React.CSSProperties;\n /** Gap between buttons in px (default: 10, compact default: 12) */\n gap?: number;\n /** Compact mode — icon-only square buttons in a row (default: false) */\n compact?: boolean;\n /** Custom labels per provider. e.g. { google: 'Google로 로그인' } */\n labels?: Partial<Record<OAuthProviderType, string>>;\n /** Props to pass through to each SocialButton */\n buttonProps?: Partial<Omit<SocialButtonProps, 'provider' | 'onClick' | 'loading' | 'disabled' | 'compact' | 'label'>>;\n}\n\nexport function SocialButtons({\n onSuccess,\n onError,\n className,\n style: userStyle,\n gap,\n compact = false,\n labels,\n buttonProps,\n}: SocialButtonsProps) {\n const { client } = useAuthon();\n const [providers, setProviders] = useState<OAuthProviderType[]>([]);\n const [loadingProvider, setLoadingProvider] = useState<string | null>(null);\n\n useEffect(() => {\n if (!client) return;\n client.getProviders().then((p: OAuthProviderType[]) => setProviders(p));\n }, [client]);\n\n if (providers.length === 0) return null;\n\n const resolvedGap = gap ?? (compact ? 12 : 10);\n\n const handleClick = async (provider: OAuthProviderType) => {\n if (!client) return;\n setLoadingProvider(provider);\n try {\n await client.signInWithOAuth(provider);\n onSuccess?.();\n } catch (e: any) {\n const error = e instanceof Error ? e : new Error(String(e));\n onError?.(error);\n } finally {\n setLoadingProvider(null);\n }\n };\n\n const containerStyle: React.CSSProperties = compact\n ? { display: 'flex', flexDirection: 'row', flexWrap: 'wrap', justifyContent: 'center', gap: resolvedGap, ...userStyle }\n : { display: 'flex', flexDirection: 'column', gap: resolvedGap, ...userStyle };\n\n return (\n <div className={className} style={containerStyle}>\n {providers.map((provider) => (\n <SocialButton\n key={provider}\n provider={provider}\n onClick={handleClick}\n loading={loadingProvider === provider}\n disabled={!!loadingProvider}\n compact={compact}\n label={labels?.[provider]}\n {...buttonProps}\n />\n ))}\n </div>\n );\n}\n"],"mappings":"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","names":["import_react","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_js","import_jsx_runtime","import_react","import_jsx_runtime"]}
package/dist/index.d.cts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { ReactNode } from 'react';
3
3
  import { Authon, AuthonConfig } from '@authon/js';
4
- import { AuthonUser } from '@authon/shared';
4
+ import { AuthonUser, OAuthProviderType } from '@authon/shared';
5
5
 
6
6
  interface AuthonContextValue {
7
7
  isSignedIn: boolean;
@@ -57,4 +57,48 @@ interface ProtectProps {
57
57
  }
58
58
  declare function Protect({ children, fallback, condition }: ProtectProps): react_jsx_runtime.JSX.Element | null;
59
59
 
60
- export { type AuthonContextValue, AuthonProvider, Protect, SignIn, SignUp, SignedIn, SignedOut, UserButton, useAuthon, useUser };
60
+ interface SocialButtonProps {
61
+ provider: OAuthProviderType;
62
+ onClick: (provider: OAuthProviderType) => void | Promise<void>;
63
+ loading?: boolean;
64
+ disabled?: boolean;
65
+ /** Override button label. Default: "Continue with {Provider}" */
66
+ label?: string;
67
+ /** Compact mode — icon-only square button (default: false) */
68
+ compact?: boolean;
69
+ /** Override button className */
70
+ className?: string;
71
+ /** Override button style */
72
+ style?: React.CSSProperties;
73
+ /** Icon size (default: 20, compact default: 24) */
74
+ iconSize?: number;
75
+ /** Border radius in px (default: 10) */
76
+ borderRadius?: number;
77
+ /** Button height in px (default: 48) */
78
+ height?: number;
79
+ /** Button size for compact mode in px (default: 48) */
80
+ size?: number;
81
+ }
82
+ declare function SocialButton({ provider, onClick, loading, disabled, label, compact, className, style: userStyle, iconSize, borderRadius, height, size, }: SocialButtonProps): react_jsx_runtime.JSX.Element;
83
+
84
+ interface SocialButtonsProps {
85
+ /** Called after successful OAuth sign-in */
86
+ onSuccess?: () => void;
87
+ /** Called on OAuth error */
88
+ onError?: (error: Error) => void;
89
+ /** Container className */
90
+ className?: string;
91
+ /** Container style */
92
+ style?: React.CSSProperties;
93
+ /** Gap between buttons in px (default: 10, compact default: 12) */
94
+ gap?: number;
95
+ /** Compact mode — icon-only square buttons in a row (default: false) */
96
+ compact?: boolean;
97
+ /** Custom labels per provider. e.g. { google: 'Google로 로그인' } */
98
+ labels?: Partial<Record<OAuthProviderType, string>>;
99
+ /** Props to pass through to each SocialButton */
100
+ buttonProps?: Partial<Omit<SocialButtonProps, 'provider' | 'onClick' | 'loading' | 'disabled' | 'compact' | 'label'>>;
101
+ }
102
+ declare function SocialButtons({ onSuccess, onError, className, style: userStyle, gap, compact, labels, buttonProps, }: SocialButtonsProps): react_jsx_runtime.JSX.Element | null;
103
+
104
+ export { type AuthonContextValue, AuthonProvider, Protect, SignIn, SignUp, SignedIn, SignedOut, SocialButton, type SocialButtonProps, SocialButtons, type SocialButtonsProps, UserButton, useAuthon, useUser };
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { ReactNode } from 'react';
3
3
  import { Authon, AuthonConfig } from '@authon/js';
4
- import { AuthonUser } from '@authon/shared';
4
+ import { AuthonUser, OAuthProviderType } from '@authon/shared';
5
5
 
6
6
  interface AuthonContextValue {
7
7
  isSignedIn: boolean;
@@ -57,4 +57,48 @@ interface ProtectProps {
57
57
  }
58
58
  declare function Protect({ children, fallback, condition }: ProtectProps): react_jsx_runtime.JSX.Element | null;
59
59
 
60
- export { type AuthonContextValue, AuthonProvider, Protect, SignIn, SignUp, SignedIn, SignedOut, UserButton, useAuthon, useUser };
60
+ interface SocialButtonProps {
61
+ provider: OAuthProviderType;
62
+ onClick: (provider: OAuthProviderType) => void | Promise<void>;
63
+ loading?: boolean;
64
+ disabled?: boolean;
65
+ /** Override button label. Default: "Continue with {Provider}" */
66
+ label?: string;
67
+ /** Compact mode — icon-only square button (default: false) */
68
+ compact?: boolean;
69
+ /** Override button className */
70
+ className?: string;
71
+ /** Override button style */
72
+ style?: React.CSSProperties;
73
+ /** Icon size (default: 20, compact default: 24) */
74
+ iconSize?: number;
75
+ /** Border radius in px (default: 10) */
76
+ borderRadius?: number;
77
+ /** Button height in px (default: 48) */
78
+ height?: number;
79
+ /** Button size for compact mode in px (default: 48) */
80
+ size?: number;
81
+ }
82
+ declare function SocialButton({ provider, onClick, loading, disabled, label, compact, className, style: userStyle, iconSize, borderRadius, height, size, }: SocialButtonProps): react_jsx_runtime.JSX.Element;
83
+
84
+ interface SocialButtonsProps {
85
+ /** Called after successful OAuth sign-in */
86
+ onSuccess?: () => void;
87
+ /** Called on OAuth error */
88
+ onError?: (error: Error) => void;
89
+ /** Container className */
90
+ className?: string;
91
+ /** Container style */
92
+ style?: React.CSSProperties;
93
+ /** Gap between buttons in px (default: 10, compact default: 12) */
94
+ gap?: number;
95
+ /** Compact mode — icon-only square buttons in a row (default: false) */
96
+ compact?: boolean;
97
+ /** Custom labels per provider. e.g. { google: 'Google로 로그인' } */
98
+ labels?: Partial<Record<OAuthProviderType, string>>;
99
+ /** Props to pass through to each SocialButton */
100
+ buttonProps?: Partial<Omit<SocialButtonProps, 'provider' | 'onClick' | 'loading' | 'disabled' | 'compact' | 'label'>>;
101
+ }
102
+ declare function SocialButtons({ onSuccess, onError, className, style: userStyle, gap, compact, labels, buttonProps, }: SocialButtonsProps): react_jsx_runtime.JSX.Element | null;
103
+
104
+ export { type AuthonContextValue, AuthonProvider, Protect, SignIn, SignUp, SignedIn, SignedOut, SocialButton, type SocialButtonProps, SocialButtons, type SocialButtonsProps, UserButton, useAuthon, useUser };
package/dist/index.js CHANGED
@@ -265,6 +265,188 @@ function Protect({ children, fallback = null, condition }) {
265
265
  if (condition && !condition(user)) return /* @__PURE__ */ jsx7(Fragment3, { children: fallback });
266
266
  return /* @__PURE__ */ jsx7(Fragment3, { children });
267
267
  }
268
+
269
+ // src/SocialButton.tsx
270
+ import { PROVIDER_COLORS, PROVIDER_DISPLAY_NAMES } from "@authon/shared";
271
+ import { getProviderButtonConfig } from "@authon/js";
272
+ import { Fragment as Fragment4, jsx as jsx8, jsxs as jsxs2 } from "react/jsx-runtime";
273
+ var baseStyle = {
274
+ display: "flex",
275
+ alignItems: "center",
276
+ justifyContent: "center",
277
+ gap: 10,
278
+ paddingLeft: 16,
279
+ paddingRight: 16,
280
+ border: "none",
281
+ cursor: "pointer",
282
+ fontFamily: "inherit",
283
+ transition: "opacity 0.15s",
284
+ width: "100%"
285
+ };
286
+ var compactBaseStyle = {
287
+ display: "flex",
288
+ alignItems: "center",
289
+ justifyContent: "center",
290
+ border: "none",
291
+ cursor: "pointer",
292
+ transition: "opacity 0.15s",
293
+ padding: 0
294
+ };
295
+ function SocialButton({
296
+ provider,
297
+ onClick,
298
+ loading = false,
299
+ disabled = false,
300
+ label,
301
+ compact = false,
302
+ className,
303
+ style: userStyle,
304
+ iconSize,
305
+ borderRadius = 10,
306
+ height = 48,
307
+ size = 48
308
+ }) {
309
+ const colors = PROVIDER_COLORS[provider] || { bg: "#333", text: "#fff" };
310
+ const displayName = PROVIDER_DISPLAY_NAMES[provider] || provider;
311
+ const buttonLabel = label ?? `Continue with ${displayName}`;
312
+ const needsBorder = colors.bg.toLowerCase() === "#ffffff";
313
+ const resolvedIconSize = iconSize ?? (compact ? 24 : 20);
314
+ const config = getProviderButtonConfig(provider);
315
+ const iconSvg = config.iconSvg.replace(/width="\d+"/, `width="${resolvedIconSize}"`).replace(/height="\d+"/, `height="${resolvedIconSize}"`);
316
+ const borderProps = needsBorder ? { border: "1px solid #dadce0" } : {};
317
+ if (compact) {
318
+ return /* @__PURE__ */ jsx8(
319
+ "button",
320
+ {
321
+ className,
322
+ style: {
323
+ ...compactBaseStyle,
324
+ backgroundColor: colors.bg,
325
+ borderRadius,
326
+ width: size,
327
+ height: size,
328
+ ...borderProps,
329
+ ...userStyle
330
+ },
331
+ onClick: () => onClick(provider),
332
+ disabled: disabled || loading,
333
+ "aria-label": `Sign in with ${displayName}`,
334
+ children: loading ? /* @__PURE__ */ jsx8(
335
+ "span",
336
+ {
337
+ style: {
338
+ display: "inline-block",
339
+ width: 16,
340
+ height: 16,
341
+ border: `2px solid ${colors.text}`,
342
+ borderTopColor: "transparent",
343
+ borderRadius: "50%",
344
+ animation: "authon-spin 0.6s linear infinite"
345
+ }
346
+ }
347
+ ) : /* @__PURE__ */ jsx8(
348
+ "span",
349
+ {
350
+ style: { display: "flex", alignItems: "center", flexShrink: 0 },
351
+ dangerouslySetInnerHTML: { __html: iconSvg }
352
+ }
353
+ )
354
+ }
355
+ );
356
+ }
357
+ return /* @__PURE__ */ jsx8(
358
+ "button",
359
+ {
360
+ className,
361
+ style: {
362
+ ...baseStyle,
363
+ backgroundColor: colors.bg,
364
+ color: colors.text,
365
+ borderRadius,
366
+ height,
367
+ ...borderProps,
368
+ ...userStyle
369
+ },
370
+ onClick: () => onClick(provider),
371
+ disabled: disabled || loading,
372
+ "aria-label": `Sign in with ${displayName}`,
373
+ children: loading ? /* @__PURE__ */ jsx8(
374
+ "span",
375
+ {
376
+ style: {
377
+ display: "inline-block",
378
+ width: 16,
379
+ height: 16,
380
+ border: `2px solid ${colors.text}`,
381
+ borderTopColor: "transparent",
382
+ borderRadius: "50%",
383
+ animation: "authon-spin 0.6s linear infinite"
384
+ }
385
+ }
386
+ ) : /* @__PURE__ */ jsxs2(Fragment4, { children: [
387
+ /* @__PURE__ */ jsx8(
388
+ "span",
389
+ {
390
+ style: { display: "flex", alignItems: "center", flexShrink: 0 },
391
+ dangerouslySetInnerHTML: { __html: iconSvg }
392
+ }
393
+ ),
394
+ /* @__PURE__ */ jsx8("span", { style: { fontSize: 15, fontWeight: 600, whiteSpace: "nowrap" }, children: buttonLabel })
395
+ ] })
396
+ }
397
+ );
398
+ }
399
+
400
+ // src/SocialButtons.tsx
401
+ import { useState as useState3, useEffect as useEffect5 } from "react";
402
+ import { jsx as jsx9 } from "react/jsx-runtime";
403
+ function SocialButtons({
404
+ onSuccess,
405
+ onError,
406
+ className,
407
+ style: userStyle,
408
+ gap,
409
+ compact = false,
410
+ labels,
411
+ buttonProps
412
+ }) {
413
+ const { client } = useAuthon();
414
+ const [providers, setProviders] = useState3([]);
415
+ const [loadingProvider, setLoadingProvider] = useState3(null);
416
+ useEffect5(() => {
417
+ if (!client) return;
418
+ client.getProviders().then((p) => setProviders(p));
419
+ }, [client]);
420
+ if (providers.length === 0) return null;
421
+ const resolvedGap = gap ?? (compact ? 12 : 10);
422
+ const handleClick = async (provider) => {
423
+ if (!client) return;
424
+ setLoadingProvider(provider);
425
+ try {
426
+ await client.signInWithOAuth(provider);
427
+ onSuccess?.();
428
+ } catch (e) {
429
+ const error = e instanceof Error ? e : new Error(String(e));
430
+ onError?.(error);
431
+ } finally {
432
+ setLoadingProvider(null);
433
+ }
434
+ };
435
+ const containerStyle = compact ? { display: "flex", flexDirection: "row", flexWrap: "wrap", justifyContent: "center", gap: resolvedGap, ...userStyle } : { display: "flex", flexDirection: "column", gap: resolvedGap, ...userStyle };
436
+ return /* @__PURE__ */ jsx9("div", { className, style: containerStyle, children: providers.map((provider) => /* @__PURE__ */ jsx9(
437
+ SocialButton,
438
+ {
439
+ provider,
440
+ onClick: handleClick,
441
+ loading: loadingProvider === provider,
442
+ disabled: !!loadingProvider,
443
+ compact,
444
+ label: labels?.[provider],
445
+ ...buttonProps
446
+ },
447
+ provider
448
+ )) });
449
+ }
268
450
  export {
269
451
  AuthonProvider,
270
452
  Protect,
@@ -272,6 +454,8 @@ export {
272
454
  SignUp,
273
455
  SignedIn,
274
456
  SignedOut,
457
+ SocialButton,
458
+ SocialButtons,
275
459
  UserButton,
276
460
  useAuthon,
277
461
  useUser
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/AuthonProvider.tsx","../src/useAuthon.ts","../src/useUser.ts","../src/SignIn.tsx","../src/SignUp.tsx","../src/UserButton.tsx","../src/SignedIn.tsx","../src/SignedOut.tsx","../src/Protect.tsx"],"sourcesContent":["import { createContext, useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport type { ReactNode } from 'react';\nimport { Authon } from '@authon/js';\nimport type { AuthonConfig } from '@authon/js';\nimport type { AuthonUser } from '@authon/shared';\n\nexport interface AuthonContextValue {\n isSignedIn: boolean;\n isLoading: boolean;\n user: AuthonUser | null;\n signOut: () => Promise<void>;\n openSignIn: () => Promise<void>;\n openSignUp: () => Promise<void>;\n getToken: () => string | null;\n client: Authon | null;\n}\n\nexport const AuthonContext = createContext<AuthonContextValue | null>(null);\n\ninterface AuthonProviderProps {\n publishableKey: string;\n children: ReactNode;\n config?: Omit<AuthonConfig, 'mode'>;\n}\n\nexport function AuthonProvider({ publishableKey, children, config }: AuthonProviderProps) {\n const [user, setUser] = useState<AuthonUser | null>(null);\n const [isLoading, setIsLoading] = useState(true);\n const clientRef = useRef<Authon | null>(null);\n\n useEffect(() => {\n const client = new Authon(publishableKey, config);\n clientRef.current = client;\n\n client.on('signedIn', (u) => {\n setUser(u as AuthonUser);\n setIsLoading(false);\n });\n\n client.on('signedOut', () => {\n setUser(null);\n });\n\n client.on('error', () => {\n setIsLoading(false);\n });\n\n const existingUser = client.getUser();\n if (existingUser) {\n setUser(existingUser);\n }\n setIsLoading(false);\n\n return () => {\n client.destroy();\n clientRef.current = null;\n };\n }, [publishableKey]);\n\n const signOut = useCallback(async () => {\n await clientRef.current?.signOut();\n setUser(null);\n }, []);\n\n const openSignIn = useCallback(async () => {\n await clientRef.current?.openSignIn();\n }, []);\n\n const openSignUp = useCallback(async () => {\n await clientRef.current?.openSignUp();\n }, []);\n\n const getToken = useCallback(() => {\n return clientRef.current?.getToken() ?? null;\n }, []);\n\n const value = useMemo<AuthonContextValue>(\n () => ({\n isSignedIn: !!user,\n isLoading,\n user,\n signOut,\n openSignIn,\n openSignUp,\n getToken,\n client: clientRef.current,\n }),\n [user, isLoading, signOut, openSignIn, openSignUp, getToken],\n );\n\n return <AuthonContext.Provider value={value}>{children}</AuthonContext.Provider>;\n}\n","import { useContext } from 'react';\nimport { AuthonContext } from './AuthonProvider';\nimport type { AuthonContextValue } from './AuthonProvider';\n\nexport function useAuthon(): AuthonContextValue {\n const ctx = useContext(AuthonContext);\n if (!ctx) {\n throw new Error('useAuthon must be used within an <AuthonProvider>');\n }\n return ctx;\n}\n","import type { AuthonUser } from '@authon/shared';\nimport { useAuthon } from './useAuthon';\n\nexport function useUser(): { user: AuthonUser | null; isLoading: boolean } {\n const { user, isLoading } = useAuthon();\n return { user, isLoading };\n}\n","import { useEffect, useRef } from 'react';\nimport { useAuthon } from './useAuthon';\n\ninterface SignInProps {\n mode?: 'popup' | 'embedded';\n redirectUrl?: string;\n}\n\nexport function SignIn({ mode = 'popup' }: SignInProps) {\n const { client } = useAuthon();\n const containerRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (mode === 'popup') {\n client?.openSignIn();\n }\n }, [client, mode]);\n\n if (mode === 'embedded') {\n return <div ref={containerRef} id=\"authon-signin-container\" />;\n }\n\n return null;\n}\n","import { useEffect } from 'react';\nimport { useAuthon } from './useAuthon';\n\ninterface SignUpProps {\n mode?: 'popup' | 'embedded';\n}\n\nexport function SignUp({ mode = 'popup' }: SignUpProps) {\n const { client } = useAuthon();\n\n useEffect(() => {\n if (mode === 'popup') {\n client?.openSignUp();\n }\n }, [client, mode]);\n\n if (mode === 'embedded') {\n return <div id=\"authon-signup-container\" />;\n }\n\n return null;\n}\n","import { useCallback, useEffect, useRef, useState } from 'react';\nimport { useAuthon } from './useAuthon';\n\nexport function UserButton() {\n const { user, signOut, openSignIn, isSignedIn } = useAuthon();\n const [open, setOpen] = useState(false);\n const dropdownRef = useRef<HTMLDivElement>(null);\n\n const handleClickOutside = useCallback((e: MouseEvent) => {\n if (dropdownRef.current && !dropdownRef.current.contains(e.target as Node)) {\n setOpen(false);\n }\n }, []);\n\n useEffect(() => {\n if (open) {\n document.addEventListener('mousedown', handleClickOutside);\n }\n return () => document.removeEventListener('mousedown', handleClickOutside);\n }, [open, handleClickOutside]);\n\n if (!isSignedIn) {\n return (\n <button\n onClick={() => openSignIn()}\n style={{\n padding: '8px 16px',\n borderRadius: '8px',\n border: 'none',\n background: 'linear-gradient(135deg, #7c3aed, #4f46e5)',\n color: '#fff',\n cursor: 'pointer',\n fontSize: '14px',\n fontWeight: 600,\n }}\n >\n Sign In\n </button>\n );\n }\n\n const initials = user?.displayName\n ? user.displayName\n .split(' ')\n .map((n) => n[0])\n .join('')\n .toUpperCase()\n .slice(0, 2)\n : (user?.email?.[0] ?? '?').toUpperCase();\n\n return (\n <div ref={dropdownRef} style={{ position: 'relative', display: 'inline-block' }}>\n <button\n onClick={() => setOpen((v) => !v)}\n style={{\n width: '36px',\n height: '36px',\n borderRadius: '50%',\n border: '2px solid #7c3aed',\n background: user?.avatarUrl ? 'transparent' : 'linear-gradient(135deg, #7c3aed, #4f46e5)',\n cursor: 'pointer',\n padding: 0,\n overflow: 'hidden',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n color: '#fff',\n fontSize: '13px',\n fontWeight: 700,\n }}\n >\n {user?.avatarUrl ? (\n <img\n src={user.avatarUrl}\n alt={user.displayName ?? 'avatar'}\n style={{ width: '100%', height: '100%', objectFit: 'cover' }}\n />\n ) : (\n initials\n )}\n </button>\n\n {open && (\n <div\n style={{\n position: 'absolute',\n right: 0,\n top: '44px',\n minWidth: '200px',\n background: '#fff',\n border: '1px solid #e5e7eb',\n borderRadius: '12px',\n boxShadow: '0 8px 24px rgba(0,0,0,0.12)',\n zIndex: 9999,\n overflow: 'hidden',\n }}\n >\n <div\n style={{\n padding: '12px 16px',\n borderBottom: '1px solid #f3f4f6',\n }}\n >\n {user?.displayName && (\n <div style={{ fontSize: '14px', fontWeight: 600, color: '#111827' }}>\n {user.displayName}\n </div>\n )}\n {user?.email && (\n <div style={{ fontSize: '12px', color: '#6b7280', marginTop: '2px' }}>\n {user.email}\n </div>\n )}\n </div>\n\n <button\n onClick={async () => {\n setOpen(false);\n await signOut();\n }}\n style={{\n display: 'block',\n width: '100%',\n padding: '10px 16px',\n textAlign: 'left',\n background: 'none',\n border: 'none',\n cursor: 'pointer',\n fontSize: '14px',\n color: '#ef4444',\n fontWeight: 500,\n }}\n onMouseEnter={(e) => {\n (e.currentTarget as HTMLButtonElement).style.background = '#fef2f2';\n }}\n onMouseLeave={(e) => {\n (e.currentTarget as HTMLButtonElement).style.background = 'none';\n }}\n >\n Sign out\n </button>\n </div>\n )}\n </div>\n );\n}\n","import type { ReactNode } from 'react';\nimport { useAuthon } from './useAuthon';\n\ninterface SignedInProps {\n children: ReactNode;\n}\n\nexport function SignedIn({ children }: SignedInProps) {\n const { isSignedIn, isLoading } = useAuthon();\n if (isLoading || !isSignedIn) return null;\n return <>{children}</>;\n}\n","import type { ReactNode } from 'react';\nimport { useAuthon } from './useAuthon';\n\ninterface SignedOutProps {\n children: ReactNode;\n}\n\nexport function SignedOut({ children }: SignedOutProps) {\n const { isSignedIn, isLoading } = useAuthon();\n if (isLoading || isSignedIn) return null;\n return <>{children}</>;\n}\n","import type { ReactNode } from 'react';\nimport type { AuthonUser } from '@authon/shared';\nimport { useAuthon } from './useAuthon';\n\ninterface ProtectProps {\n children: ReactNode;\n fallback?: ReactNode;\n condition?: (user: AuthonUser) => boolean;\n}\n\nexport function Protect({ children, fallback = null, condition }: ProtectProps) {\n const { isSignedIn, isLoading, user } = useAuthon();\n\n if (isLoading) return null;\n if (!isSignedIn || !user) return <>{fallback}</>;\n if (condition && !condition(user)) return <>{fallback}</>;\n\n return <>{children}</>;\n}\n"],"mappings":";AAAA,SAAS,eAAe,aAAa,WAAW,SAAS,QAAQ,gBAAgB;AAEjF,SAAS,cAAc;AAwFd;AAzEF,IAAM,gBAAgB,cAAyC,IAAI;AAQnE,SAAS,eAAe,EAAE,gBAAgB,UAAU,OAAO,GAAwB;AACxF,QAAM,CAAC,MAAM,OAAO,IAAI,SAA4B,IAAI;AACxD,QAAM,CAAC,WAAW,YAAY,IAAI,SAAS,IAAI;AAC/C,QAAM,YAAY,OAAsB,IAAI;AAE5C,YAAU,MAAM;AACd,UAAM,SAAS,IAAI,OAAO,gBAAgB,MAAM;AAChD,cAAU,UAAU;AAEpB,WAAO,GAAG,YAAY,CAAC,MAAM;AAC3B,cAAQ,CAAe;AACvB,mBAAa,KAAK;AAAA,IACpB,CAAC;AAED,WAAO,GAAG,aAAa,MAAM;AAC3B,cAAQ,IAAI;AAAA,IACd,CAAC;AAED,WAAO,GAAG,SAAS,MAAM;AACvB,mBAAa,KAAK;AAAA,IACpB,CAAC;AAED,UAAM,eAAe,OAAO,QAAQ;AACpC,QAAI,cAAc;AAChB,cAAQ,YAAY;AAAA,IACtB;AACA,iBAAa,KAAK;AAElB,WAAO,MAAM;AACX,aAAO,QAAQ;AACf,gBAAU,UAAU;AAAA,IACtB;AAAA,EACF,GAAG,CAAC,cAAc,CAAC;AAEnB,QAAM,UAAU,YAAY,YAAY;AACtC,UAAM,UAAU,SAAS,QAAQ;AACjC,YAAQ,IAAI;AAAA,EACd,GAAG,CAAC,CAAC;AAEL,QAAM,aAAa,YAAY,YAAY;AACzC,UAAM,UAAU,SAAS,WAAW;AAAA,EACtC,GAAG,CAAC,CAAC;AAEL,QAAM,aAAa,YAAY,YAAY;AACzC,UAAM,UAAU,SAAS,WAAW;AAAA,EACtC,GAAG,CAAC,CAAC;AAEL,QAAM,WAAW,YAAY,MAAM;AACjC,WAAO,UAAU,SAAS,SAAS,KAAK;AAAA,EAC1C,GAAG,CAAC,CAAC;AAEL,QAAM,QAAQ;AAAA,IACZ,OAAO;AAAA,MACL,YAAY,CAAC,CAAC;AAAA,MACd;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,QAAQ,UAAU;AAAA,IACpB;AAAA,IACA,CAAC,MAAM,WAAW,SAAS,YAAY,YAAY,QAAQ;AAAA,EAC7D;AAEA,SAAO,oBAAC,cAAc,UAAd,EAAuB,OAAe,UAAS;AACzD;;;AC3FA,SAAS,kBAAkB;AAIpB,SAAS,YAAgC;AAC9C,QAAM,MAAM,WAAW,aAAa;AACpC,MAAI,CAAC,KAAK;AACR,UAAM,IAAI,MAAM,mDAAmD;AAAA,EACrE;AACA,SAAO;AACT;;;ACPO,SAAS,UAA2D;AACzE,QAAM,EAAE,MAAM,UAAU,IAAI,UAAU;AACtC,SAAO,EAAE,MAAM,UAAU;AAC3B;;;ACNA,SAAS,aAAAA,YAAW,UAAAC,eAAc;AAmBvB,gBAAAC,YAAA;AAXJ,SAAS,OAAO,EAAE,OAAO,QAAQ,GAAgB;AACtD,QAAM,EAAE,OAAO,IAAI,UAAU;AAC7B,QAAM,eAAeC,QAAuB,IAAI;AAEhD,EAAAC,WAAU,MAAM;AACd,QAAI,SAAS,SAAS;AACpB,cAAQ,WAAW;AAAA,IACrB;AAAA,EACF,GAAG,CAAC,QAAQ,IAAI,CAAC;AAEjB,MAAI,SAAS,YAAY;AACvB,WAAO,gBAAAF,KAAC,SAAI,KAAK,cAAc,IAAG,2BAA0B;AAAA,EAC9D;AAEA,SAAO;AACT;;;ACvBA,SAAS,aAAAG,kBAAiB;AAiBf,gBAAAC,YAAA;AAVJ,SAAS,OAAO,EAAE,OAAO,QAAQ,GAAgB;AACtD,QAAM,EAAE,OAAO,IAAI,UAAU;AAE7B,EAAAC,WAAU,MAAM;AACd,QAAI,SAAS,SAAS;AACpB,cAAQ,WAAW;AAAA,IACrB;AAAA,EACF,GAAG,CAAC,QAAQ,IAAI,CAAC;AAEjB,MAAI,SAAS,YAAY;AACvB,WAAO,gBAAAD,KAAC,SAAI,IAAG,2BAA0B;AAAA,EAC3C;AAEA,SAAO;AACT;;;ACrBA,SAAS,eAAAE,cAAa,aAAAC,YAAW,UAAAC,SAAQ,YAAAC,iBAAgB;AAuBnD,gBAAAC,MA0EI,YA1EJ;AApBC,SAAS,aAAa;AAC3B,QAAM,EAAE,MAAM,SAAS,YAAY,WAAW,IAAI,UAAU;AAC5D,QAAM,CAAC,MAAM,OAAO,IAAIC,UAAS,KAAK;AACtC,QAAM,cAAcC,QAAuB,IAAI;AAE/C,QAAM,qBAAqBC,aAAY,CAAC,MAAkB;AACxD,QAAI,YAAY,WAAW,CAAC,YAAY,QAAQ,SAAS,EAAE,MAAc,GAAG;AAC1E,cAAQ,KAAK;AAAA,IACf;AAAA,EACF,GAAG,CAAC,CAAC;AAEL,EAAAC,WAAU,MAAM;AACd,QAAI,MAAM;AACR,eAAS,iBAAiB,aAAa,kBAAkB;AAAA,IAC3D;AACA,WAAO,MAAM,SAAS,oBAAoB,aAAa,kBAAkB;AAAA,EAC3E,GAAG,CAAC,MAAM,kBAAkB,CAAC;AAE7B,MAAI,CAAC,YAAY;AACf,WACE,gBAAAJ;AAAA,MAAC;AAAA;AAAA,QACC,SAAS,MAAM,WAAW;AAAA,QAC1B,OAAO;AAAA,UACL,SAAS;AAAA,UACT,cAAc;AAAA,UACd,QAAQ;AAAA,UACR,YAAY;AAAA,UACZ,OAAO;AAAA,UACP,QAAQ;AAAA,UACR,UAAU;AAAA,UACV,YAAY;AAAA,QACd;AAAA,QACD;AAAA;AAAA,IAED;AAAA,EAEJ;AAEA,QAAM,WAAW,MAAM,cACnB,KAAK,YACF,MAAM,GAAG,EACT,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,EACf,KAAK,EAAE,EACP,YAAY,EACZ,MAAM,GAAG,CAAC,KACZ,MAAM,QAAQ,CAAC,KAAK,KAAK,YAAY;AAE1C,SACE,qBAAC,SAAI,KAAK,aAAa,OAAO,EAAE,UAAU,YAAY,SAAS,eAAe,GAC5E;AAAA,oBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,SAAS,MAAM,QAAQ,CAAC,MAAM,CAAC,CAAC;AAAA,QAChC,OAAO;AAAA,UACL,OAAO;AAAA,UACP,QAAQ;AAAA,UACR,cAAc;AAAA,UACd,QAAQ;AAAA,UACR,YAAY,MAAM,YAAY,gBAAgB;AAAA,UAC9C,QAAQ;AAAA,UACR,SAAS;AAAA,UACT,UAAU;AAAA,UACV,SAAS;AAAA,UACT,YAAY;AAAA,UACZ,gBAAgB;AAAA,UAChB,OAAO;AAAA,UACP,UAAU;AAAA,UACV,YAAY;AAAA,QACd;AAAA,QAEC,gBAAM,YACL,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,KAAK,KAAK;AAAA,YACV,KAAK,KAAK,eAAe;AAAA,YACzB,OAAO,EAAE,OAAO,QAAQ,QAAQ,QAAQ,WAAW,QAAQ;AAAA;AAAA,QAC7D,IAEA;AAAA;AAAA,IAEJ;AAAA,IAEC,QACC;AAAA,MAAC;AAAA;AAAA,QACC,OAAO;AAAA,UACL,UAAU;AAAA,UACV,OAAO;AAAA,UACP,KAAK;AAAA,UACL,UAAU;AAAA,UACV,YAAY;AAAA,UACZ,QAAQ;AAAA,UACR,cAAc;AAAA,UACd,WAAW;AAAA,UACX,QAAQ;AAAA,UACR,UAAU;AAAA,QACZ;AAAA,QAEA;AAAA;AAAA,YAAC;AAAA;AAAA,cACC,OAAO;AAAA,gBACL,SAAS;AAAA,gBACT,cAAc;AAAA,cAChB;AAAA,cAEC;AAAA,sBAAM,eACL,gBAAAA,KAAC,SAAI,OAAO,EAAE,UAAU,QAAQ,YAAY,KAAK,OAAO,UAAU,GAC/D,eAAK,aACR;AAAA,gBAED,MAAM,SACL,gBAAAA,KAAC,SAAI,OAAO,EAAE,UAAU,QAAQ,OAAO,WAAW,WAAW,MAAM,GAChE,eAAK,OACR;AAAA;AAAA;AAAA,UAEJ;AAAA,UAEA,gBAAAA;AAAA,YAAC;AAAA;AAAA,cACC,SAAS,YAAY;AACnB,wBAAQ,KAAK;AACb,sBAAM,QAAQ;AAAA,cAChB;AAAA,cACA,OAAO;AAAA,gBACL,SAAS;AAAA,gBACT,OAAO;AAAA,gBACP,SAAS;AAAA,gBACT,WAAW;AAAA,gBACX,YAAY;AAAA,gBACZ,QAAQ;AAAA,gBACR,QAAQ;AAAA,gBACR,UAAU;AAAA,gBACV,OAAO;AAAA,gBACP,YAAY;AAAA,cACd;AAAA,cACA,cAAc,CAAC,MAAM;AACnB,gBAAC,EAAE,cAAoC,MAAM,aAAa;AAAA,cAC5D;AAAA,cACA,cAAc,CAAC,MAAM;AACnB,gBAAC,EAAE,cAAoC,MAAM,aAAa;AAAA,cAC5D;AAAA,cACD;AAAA;AAAA,UAED;AAAA;AAAA;AAAA,IACF;AAAA,KAEJ;AAEJ;;;ACvIS,0BAAAK,YAAA;AAHF,SAAS,SAAS,EAAE,SAAS,GAAkB;AACpD,QAAM,EAAE,YAAY,UAAU,IAAI,UAAU;AAC5C,MAAI,aAAa,CAAC,WAAY,QAAO;AACrC,SAAO,gBAAAA,KAAA,YAAG,UAAS;AACrB;;;ACDS,qBAAAC,WAAA,OAAAC,YAAA;AAHF,SAAS,UAAU,EAAE,SAAS,GAAmB;AACtD,QAAM,EAAE,YAAY,UAAU,IAAI,UAAU;AAC5C,MAAI,aAAa,WAAY,QAAO;AACpC,SAAO,gBAAAA,KAAAD,WAAA,EAAG,UAAS;AACrB;;;ACGmC,qBAAAE,WAAA,OAAAC,YAAA;AAJ5B,SAAS,QAAQ,EAAE,UAAU,WAAW,MAAM,UAAU,GAAiB;AAC9E,QAAM,EAAE,YAAY,WAAW,KAAK,IAAI,UAAU;AAElD,MAAI,UAAW,QAAO;AACtB,MAAI,CAAC,cAAc,CAAC,KAAM,QAAO,gBAAAA,KAAAD,WAAA,EAAG,oBAAS;AAC7C,MAAI,aAAa,CAAC,UAAU,IAAI,EAAG,QAAO,gBAAAC,KAAAD,WAAA,EAAG,oBAAS;AAEtD,SAAO,gBAAAC,KAAAD,WAAA,EAAG,UAAS;AACrB;","names":["useEffect","useRef","jsx","useRef","useEffect","useEffect","jsx","useEffect","useCallback","useEffect","useRef","useState","jsx","useState","useRef","useCallback","useEffect","jsx","Fragment","jsx","Fragment","jsx"]}
1
+ {"version":3,"sources":["../src/AuthonProvider.tsx","../src/useAuthon.ts","../src/useUser.ts","../src/SignIn.tsx","../src/SignUp.tsx","../src/UserButton.tsx","../src/SignedIn.tsx","../src/SignedOut.tsx","../src/Protect.tsx","../src/SocialButton.tsx","../src/SocialButtons.tsx"],"sourcesContent":["import { createContext, useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport type { ReactNode } from 'react';\nimport { Authon } from '@authon/js';\nimport type { AuthonConfig } from '@authon/js';\nimport type { AuthonUser } from '@authon/shared';\n\nexport interface AuthonContextValue {\n isSignedIn: boolean;\n isLoading: boolean;\n user: AuthonUser | null;\n signOut: () => Promise<void>;\n openSignIn: () => Promise<void>;\n openSignUp: () => Promise<void>;\n getToken: () => string | null;\n client: Authon | null;\n}\n\nexport const AuthonContext = createContext<AuthonContextValue | null>(null);\n\ninterface AuthonProviderProps {\n publishableKey: string;\n children: ReactNode;\n config?: Omit<AuthonConfig, 'mode'>;\n}\n\nexport function AuthonProvider({ publishableKey, children, config }: AuthonProviderProps) {\n const [user, setUser] = useState<AuthonUser | null>(null);\n const [isLoading, setIsLoading] = useState(true);\n const clientRef = useRef<Authon | null>(null);\n\n useEffect(() => {\n const client = new Authon(publishableKey, config);\n clientRef.current = client;\n\n client.on('signedIn', (u) => {\n setUser(u as AuthonUser);\n setIsLoading(false);\n });\n\n client.on('signedOut', () => {\n setUser(null);\n });\n\n client.on('error', () => {\n setIsLoading(false);\n });\n\n const existingUser = client.getUser();\n if (existingUser) {\n setUser(existingUser);\n }\n setIsLoading(false);\n\n return () => {\n client.destroy();\n clientRef.current = null;\n };\n }, [publishableKey]);\n\n const signOut = useCallback(async () => {\n await clientRef.current?.signOut();\n setUser(null);\n }, []);\n\n const openSignIn = useCallback(async () => {\n await clientRef.current?.openSignIn();\n }, []);\n\n const openSignUp = useCallback(async () => {\n await clientRef.current?.openSignUp();\n }, []);\n\n const getToken = useCallback(() => {\n return clientRef.current?.getToken() ?? null;\n }, []);\n\n const value = useMemo<AuthonContextValue>(\n () => ({\n isSignedIn: !!user,\n isLoading,\n user,\n signOut,\n openSignIn,\n openSignUp,\n getToken,\n client: clientRef.current,\n }),\n [user, isLoading, signOut, openSignIn, openSignUp, getToken],\n );\n\n return <AuthonContext.Provider value={value}>{children}</AuthonContext.Provider>;\n}\n","import { useContext } from 'react';\nimport { AuthonContext } from './AuthonProvider';\nimport type { AuthonContextValue } from './AuthonProvider';\n\nexport function useAuthon(): AuthonContextValue {\n const ctx = useContext(AuthonContext);\n if (!ctx) {\n throw new Error('useAuthon must be used within an <AuthonProvider>');\n }\n return ctx;\n}\n","import type { AuthonUser } from '@authon/shared';\nimport { useAuthon } from './useAuthon';\n\nexport function useUser(): { user: AuthonUser | null; isLoading: boolean } {\n const { user, isLoading } = useAuthon();\n return { user, isLoading };\n}\n","import { useEffect, useRef } from 'react';\nimport { useAuthon } from './useAuthon';\n\ninterface SignInProps {\n mode?: 'popup' | 'embedded';\n redirectUrl?: string;\n}\n\nexport function SignIn({ mode = 'popup' }: SignInProps) {\n const { client } = useAuthon();\n const containerRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (mode === 'popup') {\n client?.openSignIn();\n }\n }, [client, mode]);\n\n if (mode === 'embedded') {\n return <div ref={containerRef} id=\"authon-signin-container\" />;\n }\n\n return null;\n}\n","import { useEffect } from 'react';\nimport { useAuthon } from './useAuthon';\n\ninterface SignUpProps {\n mode?: 'popup' | 'embedded';\n}\n\nexport function SignUp({ mode = 'popup' }: SignUpProps) {\n const { client } = useAuthon();\n\n useEffect(() => {\n if (mode === 'popup') {\n client?.openSignUp();\n }\n }, [client, mode]);\n\n if (mode === 'embedded') {\n return <div id=\"authon-signup-container\" />;\n }\n\n return null;\n}\n","import { useCallback, useEffect, useRef, useState } from 'react';\nimport { useAuthon } from './useAuthon';\n\nexport function UserButton() {\n const { user, signOut, openSignIn, isSignedIn } = useAuthon();\n const [open, setOpen] = useState(false);\n const dropdownRef = useRef<HTMLDivElement>(null);\n\n const handleClickOutside = useCallback((e: MouseEvent) => {\n if (dropdownRef.current && !dropdownRef.current.contains(e.target as Node)) {\n setOpen(false);\n }\n }, []);\n\n useEffect(() => {\n if (open) {\n document.addEventListener('mousedown', handleClickOutside);\n }\n return () => document.removeEventListener('mousedown', handleClickOutside);\n }, [open, handleClickOutside]);\n\n if (!isSignedIn) {\n return (\n <button\n onClick={() => openSignIn()}\n style={{\n padding: '8px 16px',\n borderRadius: '8px',\n border: 'none',\n background: 'linear-gradient(135deg, #7c3aed, #4f46e5)',\n color: '#fff',\n cursor: 'pointer',\n fontSize: '14px',\n fontWeight: 600,\n }}\n >\n Sign In\n </button>\n );\n }\n\n const initials = user?.displayName\n ? user.displayName\n .split(' ')\n .map((n) => n[0])\n .join('')\n .toUpperCase()\n .slice(0, 2)\n : (user?.email?.[0] ?? '?').toUpperCase();\n\n return (\n <div ref={dropdownRef} style={{ position: 'relative', display: 'inline-block' }}>\n <button\n onClick={() => setOpen((v) => !v)}\n style={{\n width: '36px',\n height: '36px',\n borderRadius: '50%',\n border: '2px solid #7c3aed',\n background: user?.avatarUrl ? 'transparent' : 'linear-gradient(135deg, #7c3aed, #4f46e5)',\n cursor: 'pointer',\n padding: 0,\n overflow: 'hidden',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n color: '#fff',\n fontSize: '13px',\n fontWeight: 700,\n }}\n >\n {user?.avatarUrl ? (\n <img\n src={user.avatarUrl}\n alt={user.displayName ?? 'avatar'}\n style={{ width: '100%', height: '100%', objectFit: 'cover' }}\n />\n ) : (\n initials\n )}\n </button>\n\n {open && (\n <div\n style={{\n position: 'absolute',\n right: 0,\n top: '44px',\n minWidth: '200px',\n background: '#fff',\n border: '1px solid #e5e7eb',\n borderRadius: '12px',\n boxShadow: '0 8px 24px rgba(0,0,0,0.12)',\n zIndex: 9999,\n overflow: 'hidden',\n }}\n >\n <div\n style={{\n padding: '12px 16px',\n borderBottom: '1px solid #f3f4f6',\n }}\n >\n {user?.displayName && (\n <div style={{ fontSize: '14px', fontWeight: 600, color: '#111827' }}>\n {user.displayName}\n </div>\n )}\n {user?.email && (\n <div style={{ fontSize: '12px', color: '#6b7280', marginTop: '2px' }}>\n {user.email}\n </div>\n )}\n </div>\n\n <button\n onClick={async () => {\n setOpen(false);\n await signOut();\n }}\n style={{\n display: 'block',\n width: '100%',\n padding: '10px 16px',\n textAlign: 'left',\n background: 'none',\n border: 'none',\n cursor: 'pointer',\n fontSize: '14px',\n color: '#ef4444',\n fontWeight: 500,\n }}\n onMouseEnter={(e) => {\n (e.currentTarget as HTMLButtonElement).style.background = '#fef2f2';\n }}\n onMouseLeave={(e) => {\n (e.currentTarget as HTMLButtonElement).style.background = 'none';\n }}\n >\n Sign out\n </button>\n </div>\n )}\n </div>\n );\n}\n","import type { ReactNode } from 'react';\nimport { useAuthon } from './useAuthon';\n\ninterface SignedInProps {\n children: ReactNode;\n}\n\nexport function SignedIn({ children }: SignedInProps) {\n const { isSignedIn, isLoading } = useAuthon();\n if (isLoading || !isSignedIn) return null;\n return <>{children}</>;\n}\n","import type { ReactNode } from 'react';\nimport { useAuthon } from './useAuthon';\n\ninterface SignedOutProps {\n children: ReactNode;\n}\n\nexport function SignedOut({ children }: SignedOutProps) {\n const { isSignedIn, isLoading } = useAuthon();\n if (isLoading || isSignedIn) return null;\n return <>{children}</>;\n}\n","import type { ReactNode } from 'react';\nimport type { AuthonUser } from '@authon/shared';\nimport { useAuthon } from './useAuthon';\n\ninterface ProtectProps {\n children: ReactNode;\n fallback?: ReactNode;\n condition?: (user: AuthonUser) => boolean;\n}\n\nexport function Protect({ children, fallback = null, condition }: ProtectProps) {\n const { isSignedIn, isLoading, user } = useAuthon();\n\n if (isLoading) return null;\n if (!isSignedIn || !user) return <>{fallback}</>;\n if (condition && !condition(user)) return <>{fallback}</>;\n\n return <>{children}</>;\n}\n","import { PROVIDER_COLORS, PROVIDER_DISPLAY_NAMES, type OAuthProviderType } from '@authon/shared';\nimport { getProviderButtonConfig } from '@authon/js';\n\nexport interface SocialButtonProps {\n provider: OAuthProviderType;\n onClick: (provider: OAuthProviderType) => void | Promise<void>;\n loading?: boolean;\n disabled?: boolean;\n /** Override button label. Default: \"Continue with {Provider}\" */\n label?: string;\n /** Compact mode — icon-only square button (default: false) */\n compact?: boolean;\n /** Override button className */\n className?: string;\n /** Override button style */\n style?: React.CSSProperties;\n /** Icon size (default: 20, compact default: 24) */\n iconSize?: number;\n /** Border radius in px (default: 10) */\n borderRadius?: number;\n /** Button height in px (default: 48) */\n height?: number;\n /** Button size for compact mode in px (default: 48) */\n size?: number;\n}\n\nconst baseStyle: React.CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n gap: 10,\n paddingLeft: 16,\n paddingRight: 16,\n border: 'none',\n cursor: 'pointer',\n fontFamily: 'inherit',\n transition: 'opacity 0.15s',\n width: '100%',\n};\n\nconst compactBaseStyle: React.CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n border: 'none',\n cursor: 'pointer',\n transition: 'opacity 0.15s',\n padding: 0,\n};\n\nexport function SocialButton({\n provider,\n onClick,\n loading = false,\n disabled = false,\n label,\n compact = false,\n className,\n style: userStyle,\n iconSize,\n borderRadius = 10,\n height = 48,\n size = 48,\n}: SocialButtonProps) {\n const colors = PROVIDER_COLORS[provider] || { bg: '#333', text: '#fff' };\n const displayName = PROVIDER_DISPLAY_NAMES[provider] || provider;\n const buttonLabel = label ?? `Continue with ${displayName}`;\n const needsBorder = colors.bg.toLowerCase() === '#ffffff';\n const resolvedIconSize = iconSize ?? (compact ? 24 : 20);\n const config = getProviderButtonConfig(provider);\n const iconSvg = config.iconSvg.replace(/width=\"\\d+\"/, `width=\"${resolvedIconSize}\"`).replace(/height=\"\\d+\"/, `height=\"${resolvedIconSize}\"`);\n\n const borderProps = needsBorder\n ? { border: '1px solid #dadce0' }\n : {};\n\n if (compact) {\n return (\n <button\n className={className}\n style={{\n ...compactBaseStyle,\n backgroundColor: colors.bg,\n borderRadius,\n width: size,\n height: size,\n ...borderProps,\n ...userStyle,\n }}\n onClick={() => onClick(provider)}\n disabled={disabled || loading}\n aria-label={`Sign in with ${displayName}`}\n >\n {loading ? (\n <span\n style={{\n display: 'inline-block',\n width: 16,\n height: 16,\n border: `2px solid ${colors.text}`,\n borderTopColor: 'transparent',\n borderRadius: '50%',\n animation: 'authon-spin 0.6s linear infinite',\n }}\n />\n ) : (\n <span\n style={{ display: 'flex', alignItems: 'center', flexShrink: 0 }}\n dangerouslySetInnerHTML={{ __html: iconSvg }}\n />\n )}\n </button>\n );\n }\n\n return (\n <button\n className={className}\n style={{\n ...baseStyle,\n backgroundColor: colors.bg,\n color: colors.text,\n borderRadius,\n height,\n ...borderProps,\n ...userStyle,\n }}\n onClick={() => onClick(provider)}\n disabled={disabled || loading}\n aria-label={`Sign in with ${displayName}`}\n >\n {loading ? (\n <span\n style={{\n display: 'inline-block',\n width: 16,\n height: 16,\n border: `2px solid ${colors.text}`,\n borderTopColor: 'transparent',\n borderRadius: '50%',\n animation: 'authon-spin 0.6s linear infinite',\n }}\n />\n ) : (\n <>\n <span\n style={{ display: 'flex', alignItems: 'center', flexShrink: 0 }}\n dangerouslySetInnerHTML={{ __html: iconSvg }}\n />\n <span style={{ fontSize: 15, fontWeight: 600, whiteSpace: 'nowrap' }}>\n {buttonLabel}\n </span>\n </>\n )}\n </button>\n );\n}\n","import { useState, useEffect } from 'react';\nimport type { OAuthProviderType } from '@authon/shared';\nimport { useAuthon } from './useAuthon';\nimport { SocialButton } from './SocialButton';\nimport type { SocialButtonProps } from './SocialButton';\n\nexport interface SocialButtonsProps {\n /** Called after successful OAuth sign-in */\n onSuccess?: () => void;\n /** Called on OAuth error */\n onError?: (error: Error) => void;\n /** Container className */\n className?: string;\n /** Container style */\n style?: React.CSSProperties;\n /** Gap between buttons in px (default: 10, compact default: 12) */\n gap?: number;\n /** Compact mode — icon-only square buttons in a row (default: false) */\n compact?: boolean;\n /** Custom labels per provider. e.g. { google: 'Google로 로그인' } */\n labels?: Partial<Record<OAuthProviderType, string>>;\n /** Props to pass through to each SocialButton */\n buttonProps?: Partial<Omit<SocialButtonProps, 'provider' | 'onClick' | 'loading' | 'disabled' | 'compact' | 'label'>>;\n}\n\nexport function SocialButtons({\n onSuccess,\n onError,\n className,\n style: userStyle,\n gap,\n compact = false,\n labels,\n buttonProps,\n}: SocialButtonsProps) {\n const { client } = useAuthon();\n const [providers, setProviders] = useState<OAuthProviderType[]>([]);\n const [loadingProvider, setLoadingProvider] = useState<string | null>(null);\n\n useEffect(() => {\n if (!client) return;\n client.getProviders().then((p: OAuthProviderType[]) => setProviders(p));\n }, [client]);\n\n if (providers.length === 0) return null;\n\n const resolvedGap = gap ?? (compact ? 12 : 10);\n\n const handleClick = async (provider: OAuthProviderType) => {\n if (!client) return;\n setLoadingProvider(provider);\n try {\n await client.signInWithOAuth(provider);\n onSuccess?.();\n } catch (e: any) {\n const error = e instanceof Error ? e : new Error(String(e));\n onError?.(error);\n } finally {\n setLoadingProvider(null);\n }\n };\n\n const containerStyle: React.CSSProperties = compact\n ? { display: 'flex', flexDirection: 'row', flexWrap: 'wrap', justifyContent: 'center', gap: resolvedGap, ...userStyle }\n : { display: 'flex', flexDirection: 'column', gap: resolvedGap, ...userStyle };\n\n return (\n <div className={className} style={containerStyle}>\n {providers.map((provider) => (\n <SocialButton\n key={provider}\n provider={provider}\n onClick={handleClick}\n loading={loadingProvider === provider}\n disabled={!!loadingProvider}\n compact={compact}\n label={labels?.[provider]}\n {...buttonProps}\n />\n ))}\n </div>\n );\n}\n"],"mappings":"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","names":["useEffect","useRef","jsx","useRef","useEffect","useEffect","jsx","useEffect","useCallback","useEffect","useRef","useState","jsx","useState","useRef","useCallback","useEffect","jsx","Fragment","jsx","Fragment","jsx","Fragment","jsx","jsxs","useState","useEffect","jsx","useState","useEffect"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@authon/react",
3
- "version": "0.1.19",
3
+ "version": "0.2.1",
4
4
  "description": "Authon React SDK — Provider, hooks, and components for React apps",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -39,8 +39,8 @@
39
39
  "sdk"
40
40
  ],
41
41
  "dependencies": {
42
- "@authon/js": "workspace:^",
43
- "@authon/shared": "workspace:^"
42
+ "@authon/js": "^0.2.1",
43
+ "@authon/shared": "^0.2.0"
44
44
  },
45
45
  "peerDependencies": {
46
46
  "react": "^18.0.0 || ^19.0.0",