@solid/react-component 0.1.0

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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/login/AuthGuard.tsx","../src/login/NavigationContext.tsx","../src/login/SolidLoginPage.tsx","../src/login/useSolidLogin.ts","../src/login/LoginFormControl.tsx","../src/login/navigation.ts"],"sourcesContent":["/**\n * @solid/react-component\n *\n * Reusable React components for Solid apps. Each area (login, profile, etc.) is\n * available under its own subpath for tree-shaking and clear imports.\n *\n * Current components:\n * - Login: @solid/react-component/login or @solid/react-component/login/next (Next.js)\n */\n\nexport {\n AuthGuard,\n SolidLoginPage,\n LoginFormControl,\n useSolidLogin,\n validateIssuerUrl,\n SolidLoginNavigationProvider,\n useSolidLoginNavigation,\n DEFAULT_CONFIG,\n} from \"./login\";\nexport type {\n PresetIssuer,\n SolidLoginNavigation,\n SolidLoginConfig,\n} from \"./login\";\n","\"use client\";\n\nimport { useEffect, useRef, Suspense, type ReactNode } from \"react\";\nimport { useSolidAuth } from \"@ldo/solid-react\";\nimport { useSolidLoginNavigation } from \"./NavigationContext\";\n\n// ── Constants ────────────────────────────────────────────────────────────────\n\nconst RETURN_TO_KEY = \"solid-login-returnTo\";\n\n// ── Storage helpers (sessionStorage/localStorage throw in restricted contexts) ──\n\nfunction storageGet(storage: Storage, key: string): string | null {\n try {\n return storage.getItem(key);\n } catch {\n return null;\n }\n}\n\nfunction storageSet(storage: Storage, key: string, value: string): void {\n try {\n storage.setItem(key, value);\n } catch {\n // Unavailable (e.g. Safari private mode, quota exceeded)\n }\n}\n\nfunction storageRemove(storage: Storage, key: string): void {\n try {\n storage.removeItem(key);\n } catch {\n // Unavailable\n }\n}\n\n// ── Path helpers ─────────────────────────────────────────────────────────────\n\nfunction isValidReturnPath(value: string | null | undefined): value is string {\n return typeof value === \"string\" && value.startsWith(\"/\") && !value.startsWith(\"//\");\n}\n\n/**\n * Resolves where to send the user after login completes.\n *\n * Priority:\n * 1. ?returnTo= URL parameter (set by AuthGuard when redirecting to login)\n * 2. sessionStorage value (persisted before redirect to login or IdP)\n * 3. window.location.pathname (LDO restores original URL via history.replaceState\n * after silent auth — Next.js router state is stale, but the browser URL is correct)\n * 4. homePath fallback\n */\nfunction resolveReturnTo(\n searchParams: { get: (key: string) => string | null },\n loginPath: string,\n homePath: string,\n): string {\n const fromParam = searchParams.get(\"returnTo\");\n if (isValidReturnPath(fromParam)) return fromParam;\n\n if (typeof window === \"undefined\") return homePath;\n\n const fromStorage = storageGet(sessionStorage, RETURN_TO_KEY);\n if (isValidReturnPath(fromStorage)) return fromStorage;\n\n const browserPath = window.location.pathname;\n if (browserPath !== loginPath && browserPath !== homePath && isValidReturnPath(browserPath)) {\n return browserPath;\n }\n\n return homePath;\n}\n\n// ── Component ────────────────────────────────────────────────────────────────\n\nexport interface AuthGuardProps {\n children: ReactNode;\n /** Shown while session is being checked or OAuth callback is in progress */\n fallback?: ReactNode;\n}\n\nconst defaultFallback = (\n <div\n style={{\n display: \"flex\",\n minHeight: \"100vh\",\n alignItems: \"center\",\n justifyContent: \"center\",\n background: \"#fff\",\n }}\n >\n <span>Loading...</span>\n </div>\n);\n\nfunction AuthGuardContent({\n children,\n fallback = defaultFallback,\n}: AuthGuardProps) {\n // `ranInitialAuthCheck` defaults to `true` for backward compat with older\n // @ldo/solid-react versions that don't expose it. Current versions start at\n // `false` and flip to `true` after handleIncomingRedirect resolves.\n const { session, ranInitialAuthCheck = true } = useSolidAuth();\n const nav = useSolidLoginNavigation();\n\n // Derive route state from the navigation context (falls back to safe\n // defaults when the provider is missing so hooks always run).\n const pathname = nav?.navigation.getPathname() ?? \"/\";\n const searchParams = nav?.navigation.getSearchParams() ?? { has: () => false, get: () => null };\n const config = nav?.config ?? { loginPath: \"/login\", homePath: \"/\" };\n const isOAuthCallback = searchParams.has(\"code\") || searchParams.has(\"state\");\n const isLoginPage = pathname === config.loginPath;\n\n // Single redirect guard: prevents the same redirect from firing twice while\n // the previous one is still in flight (Next.js router.replace is async, so\n // the effect can re-run before the pathname has actually changed).\n const hasRedirectedRef = useRef(false);\n const prevPathnameRef = useRef(pathname);\n\n // Reset the guard when the pathname *actually* changes (the navigation we\n // triggered has completed, or the user navigated elsewhere).\n if (prevPathnameRef.current !== pathname) {\n prevPathnameRef.current = pathname;\n hasRedirectedRef.current = false;\n }\n\n // ── Effect: persist returnTo when arriving at /login?returnTo=… ──────────\n useEffect(() => {\n if (typeof window === \"undefined\" || !isLoginPage || session.isLoggedIn) return;\n const returnTo = searchParams.get(\"returnTo\");\n if (isValidReturnPath(returnTo)) {\n storageSet(sessionStorage, RETURN_TO_KEY, returnTo);\n }\n }, [isLoginPage, session.isLoggedIn]); // eslint-disable-line react-hooks/exhaustive-deps\n\n // ── Effect: main redirect logic ──────────────────────────────────────────\n //\n // Deps are limited to the values that represent meaningful state transitions.\n // `navigation` is intentionally excluded — it's a new object on every render\n // in Next.js, which would cause infinite re-runs. We read it from the ref-\n // stable `nav` context inside the effect instead.\n useEffect(() => {\n if (!nav || !ranInitialAuthCheck || hasRedirectedRef.current) return;\n const { navigation } = nav;\n\n // Re-derive inside the effect so we don't depend on the outer closures\n // that change reference every render.\n const sp = navigation.getSearchParams();\n const path = navigation.getPathname();\n const isCallback = sp.has(\"code\") || sp.has(\"state\");\n const isLogin = path === config.loginPath;\n\n // 1. OAuth callback completed — redirect to the saved return path\n if (isCallback && session.isLoggedIn) {\n hasRedirectedRef.current = true;\n let target = resolveReturnTo(sp, config.loginPath, config.homePath);\n if (target === config.loginPath) target = config.homePath;\n storageRemove(sessionStorage, RETURN_TO_KEY);\n navigation.redirect(target);\n return;\n }\n\n // 2. Already logged in but still on /login — redirect away\n if (session.isLoggedIn && isLogin && !isCallback) {\n hasRedirectedRef.current = true;\n let target = resolveReturnTo(sp, config.loginPath, config.homePath);\n if (target === config.loginPath) target = config.homePath;\n storageRemove(sessionStorage, RETURN_TO_KEY);\n navigation.replace(target);\n return;\n }\n\n // 3. Not logged in on a protected page — redirect to login\n if (!session.isLoggedIn && !isLogin && !isCallback) {\n hasRedirectedRef.current = true;\n const current = path || \"/\";\n if (current !== config.loginPath && current !== config.homePath) {\n storageSet(sessionStorage, RETURN_TO_KEY, current);\n }\n const loginUrl =\n current === config.loginPath || current === config.homePath\n ? config.loginPath\n : `${config.loginPath}?returnTo=${encodeURIComponent(current)}`;\n navigation.replace(loginUrl);\n }\n }, [ranInitialAuthCheck, session.isLoggedIn, pathname, nav, config.loginPath, config.homePath]); // eslint-disable-line react-hooks/exhaustive-deps\n\n // ── Render ───────────────────────────────────────────────────────────────\n\n if (!nav) {\n if (process.env.NODE_ENV !== \"production\") {\n console.warn(\n \"@solid/react-component: AuthGuard requires SolidLoginNavigationProvider \" +\n \"(or use '@solid/react-component/login/next')\",\n );\n }\n return <>{children}</>;\n }\n\n if (!ranInitialAuthCheck) return <>{fallback}</>;\n if (isOAuthCallback) return <>{fallback}</>;\n if (!session.isLoggedIn && !isLoginPage) return null;\n if (session.isLoggedIn && isLoginPage) return null;\n\n return <>{children}</>;\n}\n\nexport function AuthGuard(props: AuthGuardProps) {\n return (\n <Suspense fallback={props.fallback ?? defaultFallback}>\n <AuthGuardContent {...props} />\n </Suspense>\n );\n}\n","\"use client\";\n\nimport { createContext, useContext, ReactNode } from \"react\";\nimport type { SolidLoginNavigation, SolidLoginConfig } from \"./navigation\";\n\ntype NavigationContextValue = {\n navigation: SolidLoginNavigation;\n config: SolidLoginConfig;\n} | null;\n\nconst SolidLoginNavigationContext = createContext<NavigationContextValue>(null);\n\nexport function SolidLoginNavigationProvider({\n navigation,\n config,\n children,\n}: {\n navigation: SolidLoginNavigation;\n config?: Partial<SolidLoginConfig>;\n children: ReactNode;\n}) {\n const fullConfig: SolidLoginConfig = {\n loginPath: config?.loginPath ?? \"/login\",\n homePath: config?.homePath ?? \"/\",\n };\n return (\n <SolidLoginNavigationContext.Provider value={{ navigation, config: fullConfig }}>\n {children}\n </SolidLoginNavigationContext.Provider>\n );\n}\n\nexport function useSolidLoginNavigation(): NavigationContextValue {\n return useContext(SolidLoginNavigationContext);\n}\n","\"use client\";\n\nimport {\n useState,\n useEffect,\n useRef,\n useMemo,\n useId,\n ReactNode,\n} from \"react\";\nimport { useSolidLogin } from \"./useSolidLogin\";\nimport type { PresetIssuer } from \"./useSolidLogin\";\n\nexport interface SolidLoginPageProps {\n /** Redirect when already logged in (e.g. router.replace(\"/\")) */\n onAlreadyLoggedIn?: () => void;\n /** URL the IdP should redirect back to after auth. Defaults to window.location.href (the login page). */\n redirectUrl?: string;\n defaultIssuer?: string;\n presetIssuers?: PresetIssuer[];\n\n /** Logo: pass URL from the app (e.g. \"/file-manager-logo.svg\") - not shipped in package */\n logo?: string;\n logoAlt?: string;\n title?: string;\n subtitle?: string;\n inputPlaceholder?: string;\n inputLabel?: string;\n buttonLabel?: string;\n buttonLoadingLabel?: string;\n className?: string;\n\n /** Optional footer links (same as original GitHubLinks horizontal) */\n footerGitHubUrl?: string;\n footerIssuesUrl?: string;\n\n /** Slots: replace parts of the default UI */\n renderLogo?: () => ReactNode;\n renderForm?: (props: {\n issuerInput: string;\n setIssuerInput: (v: string) => void;\n error: string | null;\n presetIssuers: PresetIssuer[];\n isLoading: boolean;\n onSubmit: (e: React.FormEvent) => void;\n onIssuerChange: (v: string) => void;\n }) => ReactNode;\n renderFooter?: () => ReactNode;\n}\n\nconst defaultTitle = \"Sign in\";\nconst defaultSubtitle = \"to continue\";\n\n/** Inline SVG Chevron Down - matches heroicons 24 outline */\nfunction ChevronDownIcon({\n open,\n style,\n}: {\n open: boolean;\n style?: React.CSSProperties;\n}) {\n return (\n <svg\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n style={{\n transform: open ? \"rotate(180deg)\" : \"rotate(0deg)\",\n transition: \"transform 0.2s\",\n ...style,\n }}\n aria-hidden\n >\n <path d=\"m6 9 6 6 6-6\" />\n </svg>\n );\n}\n\n/** GitHub octocat icon - same path as original GitHubLinks */\nfunction GitHubIcon({ style }: { style?: React.CSSProperties }) {\n return (\n <svg\n width=\"16\"\n height=\"16\"\n fill=\"currentColor\"\n viewBox=\"0 0 24 24\"\n aria-hidden\n style={style}\n >\n <path\n fillRule=\"evenodd\"\n d=\"M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z\"\n clipRule=\"evenodd\"\n />\n </svg>\n );\n}\n\n/** Warning triangle icon - matches ExclamationTriangleIcon */\nfunction ReportIssueIcon({ style }: { style?: React.CSSProperties }) {\n return (\n <svg\n width=\"16\"\n height=\"16\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n aria-hidden\n style={style}\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z\"\n />\n </svg>\n );\n}\n\n/** Loading spinner for button - minimal, no extra deps */\nfunction ButtonSpinner() {\n return (\n <span\n style={{\n display: \"inline-block\",\n width: 14,\n height: 14,\n border: \"2px solid transparent\",\n borderTopColor: \"currentColor\",\n borderRadius: \"50%\",\n animation: \"solid-login-spin 0.6s linear infinite\",\n marginRight: 8,\n verticalAlign: \"middle\",\n }}\n />\n );\n}\n\nexport function SolidLoginPage({\n onAlreadyLoggedIn,\n redirectUrl,\n defaultIssuer,\n presetIssuers,\n logo,\n logoAlt = \"Logo\",\n title = defaultTitle,\n subtitle = defaultSubtitle,\n inputPlaceholder = \"Enter your provider URL or select from the list\",\n inputLabel = \"Solid Identity Provider\",\n buttonLabel = \"Next\",\n buttonLoadingLabel = \"Signing in...\",\n className = \"\",\n footerGitHubUrl,\n footerIssuesUrl,\n renderLogo,\n renderForm,\n renderFooter,\n}: SolidLoginPageProps) {\n const {\n session,\n issuerInput,\n setIssuerInput,\n isLoading,\n error,\n presetIssuers: presets,\n validateAndSubmit,\n } = useSolidLogin({ defaultIssuer, presetIssuers, redirectUrl });\n\n const [showDropdown, setShowDropdown] = useState(false);\n const [highlightedIndex, setHighlightedIndex] = useState(-1);\n const inputRef = useRef<HTMLInputElement>(null);\n const dropdownRef = useRef<HTMLDivElement>(null);\n const generatedId = useId();\n const inputId = `solid-login-combobox-${generatedId}`;\n const listboxId = `${inputId}-listbox`;\n\n useEffect(() => {\n if (session.isLoggedIn && onAlreadyLoggedIn) onAlreadyLoggedIn();\n }, [session.isLoggedIn, onAlreadyLoggedIn]);\n\n useEffect(() => {\n const handleClickOutside = (e: MouseEvent) => {\n if (\n dropdownRef.current &&\n !dropdownRef.current.contains(e.target as Node) &&\n inputRef.current &&\n !inputRef.current.contains(e.target as Node)\n ) {\n setShowDropdown(false);\n }\n };\n if (showDropdown) {\n document.addEventListener(\"mousedown\", handleClickOutside);\n return () => document.removeEventListener(\"mousedown\", handleClickOutside);\n }\n }, [showDropdown]);\n\n const filteredOptions = useMemo(() => {\n if (!issuerInput.trim()) return presets;\n const q = issuerInput.toLowerCase();\n return presets.filter(\n (o) =>\n o.label.toLowerCase().includes(q) ||\n o.value.toLowerCase().includes(q) ||\n (o.secondaryLabel && o.secondaryLabel.toLowerCase().includes(q))\n );\n }, [issuerInput, presets]);\n\n if (session.isLoggedIn) return null;\n\n const handleSubmit = (e: React.FormEvent) => {\n e.preventDefault();\n validateAndSubmit();\n };\n\n const handleSelect = (option: PresetIssuer) => {\n setIssuerInput(option.value);\n setShowDropdown(false);\n setHighlightedIndex(-1);\n inputRef.current?.focus();\n };\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (!showDropdown) {\n if (e.key === \"ArrowDown\" || e.key === \"ArrowUp\") {\n e.preventDefault();\n setShowDropdown(true);\n setHighlightedIndex(-1);\n }\n return;\n }\n switch (e.key) {\n case \"ArrowDown\":\n e.preventDefault();\n setHighlightedIndex((prev) =>\n prev < filteredOptions.length - 1 ? prev + 1 : prev\n );\n break;\n case \"ArrowUp\":\n e.preventDefault();\n setHighlightedIndex((prev) => (prev > 0 ? prev - 1 : prev));\n break;\n case \"Enter\":\n if (\n highlightedIndex >= 0 &&\n highlightedIndex < filteredOptions.length\n ) {\n e.preventDefault();\n handleSelect(filteredOptions[highlightedIndex]);\n }\n break;\n case \"Escape\":\n e.preventDefault();\n setShowDropdown(false);\n setHighlightedIndex(-1);\n break;\n }\n };\n\n const formProps = {\n issuerInput,\n setIssuerInput,\n error,\n presetIssuers: presets,\n isLoading,\n onSubmit: handleSubmit,\n onIssuerChange: setIssuerInput,\n };\n\n if (renderForm) {\n return (\n <main\n className={className}\n role=\"main\"\n aria-label=\"Sign in page\"\n style={{ display: \"flex\", minHeight: \"100vh\", background: \"#fff\" }}\n >\n {renderForm(formProps)}\n </main>\n );\n }\n\n const showFooter =\n renderFooter ||\n (footerGitHubUrl != null && footerIssuesUrl != null);\n\n return (\n <>\n <style>{`\n @keyframes solid-login-spin {\n to { transform: rotate(360deg); }\n }\n .solid-login-combobox-input:focus {\n border-color: #7B42F6;\n box-shadow: 0 0 0 1px #7B42F6;\n }\n @media (max-width: 1023px) {\n .solid-login-left-panel { display: none !important; }\n .solid-login-mobile-header { display: flex !important; }\n }\n @media (min-width: 1024px) {\n .solid-login-mobile-header { display: none !important; }\n }\n @media (min-width: 1024px) {\n .solid-login-right-panel { min-width: 450px; }\n }\n `}</style>\n <main\n className={className}\n role=\"main\"\n aria-label=\"Sign in page\"\n style={{\n display: \"flex\",\n flexDirection: \"row\",\n flexWrap: \"wrap\",\n minHeight: \"100vh\",\n background: \"#fff\",\n }}\n >\n {/* Left - Logo and branding (hidden on mobile) */}\n <section\n className=\"solid-login-left-panel\"\n aria-label=\"Branding section\"\n style={{\n display: \"flex\",\n flex: \"1 1 50%\",\n minWidth: 280,\n alignItems: \"center\",\n justifyContent: \"center\",\n borderRight: \"1px solid #e5e7eb\",\n background: \"#F3EDFF\",\n padding: \"2rem\",\n }}\n >\n <div style={{ maxWidth: \"28rem\", width: \"100%\" }}>\n <header\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n gap: 4,\n }}\n >\n {renderLogo ? (\n renderLogo()\n ) : logo ? (\n <div\n style={{\n width: 300,\n height: 90,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n }}\n >\n <img\n src={logo}\n alt={logoAlt}\n style={{ width: \"100%\", height: \"100%\", objectFit: \"contain\" }}\n />\n </div>\n ) : null}\n <h1\n style={{\n marginBottom: 2,\n fontSize: \"2.25rem\",\n fontWeight: 400,\n color: \"#000\",\n }}\n >\n {title}\n </h1>\n <p style={{ fontSize: \"1rem\", color: \"#4b5563\" }}>{subtitle}</p>\n </header>\n </div>\n </section>\n\n {/* Right - Form */}\n <section\n className=\"solid-login-right-panel\"\n aria-label=\"Sign in form section\"\n style={{\n display: \"flex\",\n flex: \"1 1 50%\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n background: \"#fff\",\n padding: \"3rem 1rem\",\n minWidth: 0,\n minHeight: 320,\n }}\n >\n <div style={{ width: \"100%\", maxWidth: \"28rem\" }}>\n {/* Mobile header (visible only on small screens) */}\n <header\n className=\"solid-login-mobile-header\"\n style={{\n display: \"none\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n marginBottom: \"2rem\",\n }}\n >\n {renderLogo ? (\n renderLogo()\n ) : logo ? (\n <div\n style={{\n width: 300,\n height: 90,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n marginBottom: 8,\n }}\n >\n <img\n src={logo}\n alt={logoAlt}\n style={{ width: \"100%\", height: \"100%\", objectFit: \"contain\" }}\n />\n </div>\n ) : null}\n <h1\n style={{\n marginBottom: 8,\n fontSize: \"1.875rem\",\n fontWeight: 400,\n color: \"#000\",\n textAlign: \"center\",\n }}\n >\n {title}\n </h1>\n <p style={{ fontSize: \"1rem\", color: \"#4b5563\", textAlign: \"center\" }}>\n {subtitle}\n </p>\n </header>\n\n <form\n onSubmit={handleSubmit}\n aria-label=\"Sign in form\"\n noValidate\n style={{ display: \"flex\", flexDirection: \"column\", gap: \"1.5rem\" }}\n >\n <label\n htmlFor={inputId}\n style={{\n display: \"block\",\n marginBottom: 8,\n fontSize: \"0.875rem\",\n fontWeight: 500,\n color: \"#000\",\n }}\n >\n {inputLabel}\n </label>\n\n {/* UrlCombobox-style: input + chevron, dropdown below */}\n <div style={{ position: \"relative\" }}>\n <input\n ref={inputRef}\n id={inputId}\n type=\"text\"\n value={issuerInput}\n onChange={(e) => setIssuerInput(e.target.value)}\n onFocus={() => {\n setShowDropdown(true);\n setHighlightedIndex(-1);\n }}\n onKeyDown={handleKeyDown}\n placeholder={inputPlaceholder}\n disabled={isLoading}\n aria-invalid={!!error}\n aria-expanded={showDropdown}\n aria-controls={listboxId}\n aria-autocomplete=\"list\"\n aria-activedescendant={\n highlightedIndex >= 0\n ? `${inputId}-option-${highlightedIndex}`\n : undefined\n }\n role=\"combobox\"\n autoComplete=\"off\"\n className=\"solid-login-combobox-input\"\n style={{\n width: \"100%\",\n height: 48,\n paddingLeft: 16,\n paddingRight: 40,\n fontSize: \"1rem\",\n color: \"#000\",\n background: \"#fff\",\n border: `1px solid ${error ? \"#fca5a5\" : \"#d1d5db\"}`,\n borderRadius: 6,\n outline: \"none\",\n boxSizing: \"border-box\",\n }}\n onBlur={() => {}}\n />\n <button\n type=\"button\"\n onClick={() => {\n setShowDropdown(!showDropdown);\n inputRef.current?.focus();\n }}\n aria-label={showDropdown ? \"Hide options\" : \"Show options\"}\n aria-expanded={showDropdown}\n tabIndex={-1}\n style={{\n position: \"absolute\",\n right: 12,\n top: \"50%\",\n transform: \"translateY(-50%)\",\n padding: 0,\n border: \"none\",\n background: \"none\",\n cursor: \"pointer\",\n color: \"#9ca3af\",\n }}\n >\n <ChevronDownIcon open={showDropdown} />\n </button>\n\n {showDropdown && filteredOptions.length > 0 && (\n <div\n ref={dropdownRef}\n id={listboxId}\n role=\"listbox\"\n aria-label=\"Options\"\n style={{\n position: \"absolute\",\n zIndex: 10,\n marginTop: 4,\n width: \"100%\",\n maxHeight: 240,\n overflow: \"auto\",\n border: \"1px solid #e5e7eb\",\n borderRadius: 6,\n background: \"#fff\",\n boxShadow: \"0 10px 15px -3px rgba(0,0,0,0.1), 0 4px 6px -2px rgba(0,0,0,0.05)\",\n }}\n >\n {filteredOptions.map((option, index) => (\n <button\n key={option.value}\n id={`${inputId}-option-${index}`}\n type=\"button\"\n role=\"option\"\n aria-selected={issuerInput === option.value}\n onClick={() => handleSelect(option)}\n onMouseEnter={() => setHighlightedIndex(index)}\n style={{\n width: \"100%\",\n padding: \"12px 16px\",\n textAlign: \"left\",\n border: \"none\",\n background:\n highlightedIndex === index ? \"#f3f4f6\" : \"transparent\",\n cursor: \"pointer\",\n fontSize: \"0.875rem\",\n color: \"#111\",\n }}\n >\n <div style={{ fontWeight: 500, marginBottom: 2 }}>\n {option.label}\n </div>\n {option.secondaryLabel && (\n <div\n style={{\n fontSize: \"0.75rem\",\n color: \"#6b7280\",\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n }}\n >\n {option.secondaryLabel}\n </div>\n )}\n </button>\n ))}\n </div>\n )}\n </div>\n\n {error && (\n <p\n role=\"alert\"\n style={{ fontSize: \"0.75rem\", color: \"#dc2626\", marginTop: 4 }}\n >\n {error}\n </p>\n )}\n\n <div\n style={{\n display: \"flex\",\n justifyContent: \"flex-end\",\n paddingTop: 16,\n }}\n >\n <button\n type=\"submit\"\n disabled={isLoading}\n aria-busy={isLoading}\n aria-label={\n isLoading ? \"Signing in, please wait\" : \"Continue to sign in\"\n }\n style={{\n padding: \"8px 16px\",\n fontSize: \"0.875rem\",\n fontWeight: 500,\n color: \"#fff\",\n background: isLoading ? \"#d1d5db\" : \"#7B42F6\",\n border: \"none\",\n borderRadius: 6,\n cursor: isLoading ? \"not-allowed\" : \"pointer\",\n display: \"inline-flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n boxShadow: \"none\",\n }}\n >\n {isLoading ? (\n <>\n <ButtonSpinner />\n {buttonLoadingLabel}\n </>\n ) : (\n buttonLabel\n )}\n </button>\n </div>\n </form>\n\n {showFooter && (\n <footer\n className=\"solid-login-footer-wrap\"\n style={{\n marginTop: \"6rem\",\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"flex-end\",\n width: \"100%\",\n }}\n >\n {renderFooter ? (\n renderFooter()\n ) : (\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 16,\n fontSize: \"0.875rem\",\n color: \"#6b7280\",\n }}\n >\n <a\n href={footerGitHubUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n style={{\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: 6,\n color: \"inherit\",\n textDecoration: \"none\",\n }}\n aria-label=\"View source code on GitHub\"\n >\n <GitHubIcon />\n <span>GitHub</span>\n </a>\n <span style={{ color: \"#d1d5db\" }}>·</span>\n <a\n href={footerIssuesUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n style={{\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: 6,\n color: \"inherit\",\n textDecoration: \"none\",\n }}\n aria-label=\"Report an issue on GitHub\"\n >\n <ReportIssueIcon />\n <span>Report an issue</span>\n </a>\n </div>\n )}\n </footer>\n )}\n </div>\n </section>\n </main>\n </>\n );\n}\n","\"use client\";\n\nimport { useState, useCallback } from \"react\";\nimport { useSolidAuth } from \"@ldo/solid-react\";\n\nexport interface PresetIssuer {\n label: string;\n value: string;\n secondaryLabel?: string;\n}\n\nconst DEFAULT_PRESETS: PresetIssuer[] = [\n { label: \"Solid Community\", value: \"https://solidcommunity.net/\", secondaryLabel: \"https://solidcommunity.net/\" },\n { label: \"Inrupt\", value: \"https://login.inrupt.com\", secondaryLabel: \"https://login.inrupt.com\" },\n];\n\nexport function validateIssuerUrl(url: string): { valid: boolean; error: string | null } {\n if (!url.trim()) return { valid: false, error: \"Please enter a Solid Identity Provider URL\" };\n try {\n const parsed = new URL(url);\n if (parsed.protocol !== \"http:\" && parsed.protocol !== \"https:\") {\n return { valid: false, error: \"URL must start with http:// or https://\" };\n }\n } catch {\n return { valid: false, error: \"Please enter a valid URL\" };\n }\n return { valid: true, error: null };\n}\n\nexport interface UseSolidLoginOptions {\n /** URL the IdP should redirect back to after authentication. Defaults to window.location.href. */\n redirectUrl?: string;\n defaultIssuer?: string;\n presetIssuers?: PresetIssuer[];\n onAlreadyLoggedIn?: () => void;\n}\n\nexport function useSolidLogin(options: UseSolidLoginOptions = {}) {\n const { session, login } = useSolidAuth();\n const [issuerInput, setIssuerInput] = useState(options.defaultIssuer ?? \"\");\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n const presetIssuers = options.presetIssuers ?? DEFAULT_PRESETS;\n\n const validateAndSubmit = useCallback(async (): Promise<boolean> => {\n const trimmed = issuerInput.trim();\n const { valid, error: err } = validateIssuerUrl(trimmed);\n if (!valid) {\n setError(err);\n return false;\n }\n setError(null);\n setIsLoading(true);\n try {\n await login(trimmed, options.redirectUrl ? { redirectUrl: options.redirectUrl } : undefined);\n return true;\n } catch (e) {\n console.error(\"Login failed:\", e);\n setIsLoading(false);\n return false;\n }\n }, [issuerInput, login, options.redirectUrl]);\n\n const setIssuer = useCallback((value: string) => {\n setIssuerInput(value);\n setError(null);\n }, []);\n\n return {\n session,\n issuerInput,\n setIssuerInput: setIssuer,\n isLoading,\n error,\n presetIssuers,\n validateAndSubmit,\n login,\n };\n}\n","\"use client\";\n\nimport { ReactNode } from \"react\";\nimport { useSolidLogin } from \"./useSolidLogin\";\n\nexport interface LoginFormControlProps {\n children: (props: {\n issuerInput: string;\n setIssuerInput: (v: string) => void;\n isLoading: boolean;\n error: string | null;\n presetIssuers: { label: string; value: string; secondaryLabel?: string }[];\n onSubmit: (e: React.FormEvent) => void;\n onIssuerChange: (v: string) => void;\n }) => ReactNode;\n defaultIssuer?: string;\n presetIssuers?: { label: string; value: string; secondaryLabel?: string }[];\n}\n\nexport function LoginFormControl({\n children,\n defaultIssuer,\n presetIssuers,\n}: LoginFormControlProps) {\n const {\n session,\n issuerInput,\n setIssuerInput,\n isLoading,\n error,\n presetIssuers: presets,\n validateAndSubmit,\n } = useSolidLogin({ defaultIssuer, presetIssuers });\n\n if (session.isLoggedIn) return null;\n\n const handleSubmit = (e: React.FormEvent) => {\n e.preventDefault();\n validateAndSubmit();\n };\n\n return (\n <>\n {children({\n issuerInput,\n setIssuerInput,\n isLoading,\n error,\n presetIssuers: presets,\n onSubmit: handleSubmit,\n onIssuerChange: setIssuerInput,\n })}\n </>\n );\n}\n","/**\n * Navigation interface for auth redirects and route checks.\n * Implement this (e.g. via Next.js useRouter/usePathname/useSearchParams)\n * and provide it through SolidLoginNavigationContext so AuthGuard works in any React app.\n */\nexport interface SolidLoginNavigation {\n /** Current pathname, e.g. \"/login\" */\n getPathname: () => string;\n /** Read-only view of search params; must support .has(key) and .get(key) */\n getSearchParams: () => { has: (key: string) => boolean; get: (key: string) => string | null };\n /** Navigate to path (replace current history entry). Used for redirect to login or home. */\n replace: (path: string) => void;\n /** Full page redirect (e.g. window.location.href). Used after OAuth callback to clear URL. */\n redirect: (path: string) => void;\n}\n\nexport interface SolidLoginConfig {\n /** Path for the login page, e.g. \"/login\". AuthGuard redirects here when not authenticated. */\n loginPath: string;\n /** Path after successful login, e.g. \"/\". */\n homePath: string;\n}\n\nexport const DEFAULT_CONFIG: SolidLoginConfig = {\n loginPath: \"/login\",\n homePath: \"/\",\n};\n"],"mappings":"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","names":["import_react","import_jsx_runtime","import_react","import_react","import_solid_react","import_jsx_runtime","import_jsx_runtime"]}
@@ -0,0 +1,5 @@
1
+ export { A as AuthGuard, D as DEFAULT_CONFIG, P as PresetIssuer, S as SolidLoginConfig, b as SolidLoginNavigation, a as SolidLoginPage, u as useSolidLogin, v as validateIssuerUrl } from './navigation-8m8VBbGz.cjs';
2
+ export { LoginFormControl, SolidLoginNavigationProvider, useSolidLoginNavigation } from './login/index.cjs';
3
+ import 'react/jsx-runtime';
4
+ import 'react';
5
+ import '@inrupt/solid-client-authn-core';
@@ -0,0 +1,5 @@
1
+ export { A as AuthGuard, D as DEFAULT_CONFIG, P as PresetIssuer, S as SolidLoginConfig, b as SolidLoginNavigation, a as SolidLoginPage, u as useSolidLogin, v as validateIssuerUrl } from './navigation-8m8VBbGz.js';
2
+ export { LoginFormControl, SolidLoginNavigationProvider, useSolidLoginNavigation } from './login/index.js';
3
+ import 'react/jsx-runtime';
4
+ import 'react';
5
+ import '@inrupt/solid-client-authn-core';