UNPKG

aau-auth-kit-ui

Version:

Plug & play shadcn/ui components for aau-auth-kit with Next.js integration

667 lines (607 loc) 24 kB
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }// src/lib/auth-view-paths.ts var authViewPaths = { callback: "callback", forgotPassword: "forgot-password", resetPassword: "reset-password", settings: "settings", signIn: "sign-in", signOut: "sign-out", signUp: "sign-up", twoFactor: "two-factor", signInPhone: "sign-in-phone", sendOtp: "send-otp" }; // src/lib/auth-ui-provider.tsx var _react = require('react'); var React = _interopRequireWildcard(_react); var React2 = _interopRequireWildcard(_react); var _sonner = require('sonner'); // src/hooks/use-auth-data.ts function useAuthData({ queryFn }) { const { authClient, toast: toast2 } = _react.useContext.call(void 0, AuthUIContext); const { data: sessionData, isPending: sessionPending } = authClient.useSession(); const [data, setData] = _react.useState.call(void 0, null); const [isPending, setIsPending] = _react.useState.call(void 0, true); const initialized = _react.useRef.call(void 0, false); const refetch = _react.useCallback.call(void 0, async () => { const { data: data2, error } = await queryFn(); if (error) toast2({ variant: "error", message: error.message || "An error occurred" }); setData(data2); setIsPending(false); }, [queryFn, toast2]); _react.useEffect.call(void 0, () => { if (!sessionData) { setIsPending(sessionPending); setData(null); initialized.current = false; return; } if (initialized.current) return; initialized.current = true; refetch(); }, [refetch, sessionData, sessionPending]); return { data, isPending, refetch }; } // src/lib/auth-ui-provider.tsx var _jsxruntime = require('react/jsx-runtime'); var defaultRole = [ { key: "owner", value: "Owner" }, { key: "member", value: "Member" }, { key: "admin", value: "Admin" } ]; var DefaultLink = ({ href, className, children }) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "a", { className, href, children }); var defaultNavigate = (href) => { window.location.href = href; }; var defaultPathname = () => window.location.pathname; var defaultReplace = (href) => { window.location.replace(href); }; var defaultToast = ({ variant = "default", message }) => { if (variant === "default") { _sonner.toast.call(void 0, message); } else { _sonner.toast[variant](message); } }; var AuthUIContext = _react.createContext.call(void 0, {} ); var AuthUIProvider = ({ children, authClient, avatarExtension = "png", avatarSize, basePath = "/auth", baseURL = "", redirectTo = "/", credentials = true, forgotPassword = true, freshAge = 60 * 60 * 24, hooks: hooksProp, mutators: mutatorsProp, nameRequired = true, settingsFields = ["name"], signUp = true, signUpFields = ["name"], toast: toast2 = defaultToast, viewPaths: viewPathsProp, navigate, replace, uploadAvatar, Link = DefaultLink, pathname, adminRole, roles, ...props }) => { const defaultMutators = _react.useMemo.call(void 0, () => { return { revokeSession: (params) => authClient.revokeSession({ ...params, fetchOptions: { throw: true } }), updateUser: (params) => authClient.updateUser({ ...params, fetchOptions: { throw: true } }) }; }, [authClient]); const defaultHooks = _react.useMemo.call(void 0, () => { return { useSession: authClient.useSession, useListAccounts: () => useAuthData({ queryFn: authClient.listAccounts }), useListSessions: () => useAuthData({ queryFn: authClient.listSessions }) }; }, [authClient]); const viewPaths = _react.useMemo.call(void 0, () => { return { ...authViewPaths, ...viewPathsProp }; }, [viewPathsProp]); const hooks = _react.useMemo.call(void 0, () => { return { ...defaultHooks, ...hooksProp }; }, [defaultHooks, hooksProp]); const mutators = _react.useMemo.call(void 0, () => { return { ...defaultMutators, ...mutatorsProp }; }, [defaultMutators, mutatorsProp]); baseURL = baseURL.endsWith("/") ? baseURL.slice(0, -1) : baseURL; basePath = basePath.endsWith("/") ? basePath.slice(0, -1) : basePath; const admin = _nullishCoalesce(adminRole, () => ( "admin")); const finalRoles = _nullishCoalesce(roles, () => ( defaultRole)); return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, AuthUIContext.Provider, { value: { roles: finalRoles, authClient, avatarExtension, avatarSize: avatarSize || (uploadAvatar ? 256 : 128), basePath: basePath === "/" ? "" : basePath, baseURL, redirectTo, credentials, forgotPassword, freshAge, hooks, mutators, nameRequired, settingsFields, signUp, signUpFields, toast: toast2, navigate: navigate || defaultNavigate, pathname: pathname || defaultPathname, replace: replace || navigate || defaultReplace, viewPaths, uploadAvatar, Link, adminRole: admin, ...props }, children } ); }; // src/components/ui/button.tsx var _reactslot = require('@radix-ui/react-slot'); var _classvarianceauthority = require('class-variance-authority'); // src/lib/utils.ts var _clsx = require('clsx'); var _tailwindmerge = require('tailwind-merge'); function cn(...inputs) { return _tailwindmerge.twMerge.call(void 0, _clsx.clsx.call(void 0, inputs)); } function isValidEmail(email) { const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; return emailRegex.test(email); } function errorCodeToCamelCase(errorCode) { return errorCode.toLowerCase().replace(/_([a-z])/g, (_, char) => char.toUpperCase()); } function getLocalizedError({ error, localization }) { if (_optionalChain([error, 'optionalAccess', _2 => _2.error])) { if (error.error.code) { const camelCaseErrorCode = errorCodeToCamelCase( error.error.code ); if (_optionalChain([localization, 'optionalAccess', _3 => _3[camelCaseErrorCode]])) return localization[camelCaseErrorCode]; } return error.error.message || error.error.code || error.error.statusText || _optionalChain([localization, 'optionalAccess', _4 => _4.requestFailed]); } return _optionalChain([error, 'optionalAccess', _5 => _5.message]) || _optionalChain([localization, 'optionalAccess', _6 => _6.requestFailed]) || "Request failed"; } function getSearchParam(paramName) { return typeof window !== "undefined" ? new URLSearchParams(window.location.search).get(paramName) : null; } function getAuthViewByPath(authViewPaths2, path) { for (const authViewPathsKey in authViewPaths2) { if (authViewPaths2[authViewPathsKey] === path) { return authViewPathsKey; } } } // src/components/ui/button.tsx var buttonVariants = _classvarianceauthority.cva.call(void 0, "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive", { variants: { variant: { default: "bg-primary text-primary-foreground shadow-xs hover:bg-primary/90", destructive: "bg-destructive text-white shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60", outline: "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50", secondary: "bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80", ghost: "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50", link: "text-primary underline-offset-4 hover:underline" }, size: { default: "h-9 px-4 py-2 has-[>svg]:px-3", sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5", lg: "h-10 rounded-md px-6 has-[>svg]:px-4", icon: "size-9" } }, defaultVariants: { variant: "default", size: "default" } } ); function Button({ className, variant, size, asChild = false, ...props }) { const Comp = asChild ? _reactslot.Slot : "button"; return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Comp, { "data-slot": "button", className: cn(buttonVariants({ variant, size, className })), ...props } ); } // src/components/ui/input.tsx function Input({ className, type, ...props }) { return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "input", { type, "data-slot": "input", className: cn( "file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input flex h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm", "focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]", "aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive", className ), ...props } ); } // src/components/ui/dialog.tsx var _reactdialog = require('@radix-ui/react-dialog'); var DialogPrimitive = _interopRequireWildcard(_reactdialog); var _lucidereact = require('lucide-react'); function Dialog({ ...props }) { return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, DialogPrimitive.Root, { "data-slot": "dialog", ...props }); } function DialogPortal({ ...props }) { return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, DialogPrimitive.Portal, { "data-slot": "dialog-portal", ...props }); } function DialogClose({ ...props }) { return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, DialogPrimitive.Close, { "data-slot": "dialog-close", ...props }); } function DialogOverlay({ className, ...props }) { return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, DialogPrimitive.Overlay, { "data-slot": "dialog-overlay", className: cn( "data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50", className ), ...props } ); } function DialogContent({ className, children, ...props }) { return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, DialogPortal, { "data-slot": "dialog-portal", children: [ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, DialogOverlay, {}), /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, DialogPrimitive.Content, { "data-slot": "dialog-content", className: cn( "bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 sm:max-w-lg", className ), ...props, children: [ children, /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, DialogPrimitive.Close, { className: "ring-offset-background focus:ring-ring data-[state=open]:bg-accent data-[state=open]:text-muted-foreground absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", children: [ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.XIcon, {}), /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "sr-only", children: "Close" }) ] }) ] } ) ] }); } function DialogHeader({ className, ...props }) { return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { "data-slot": "dialog-header", className: cn("flex flex-col gap-2 text-center sm:text-left", className), ...props } ); } function DialogFooter({ className, ...props }) { return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { "data-slot": "dialog-footer", className: cn( "flex flex-col-reverse gap-2 sm:flex-row sm:justify-end", className ), ...props } ); } function DialogTitle({ className, ...props }) { return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, DialogPrimitive.Title, { "data-slot": "dialog-title", className: cn("text-lg leading-none font-semibold", className), ...props } ); } function DialogDescription({ className, ...props }) { return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, DialogPrimitive.Description, { "data-slot": "dialog-description", className: cn("text-muted-foreground text-sm", className), ...props } ); } // src/components/ui/form.tsx var _reacthookform = require('react-hook-form'); // src/components/ui/label.tsx var _reactlabel = require('@radix-ui/react-label'); var LabelPrimitive = _interopRequireWildcard(_reactlabel); function Label({ className, ...props }) { return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, LabelPrimitive.Root, { "data-slot": "label", className: cn( "flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50", className ), ...props } ); } // src/components/ui/form.tsx var Form = _reacthookform.FormProvider; var FormFieldContext = React.createContext( {} ); var FormField = ({ ...props }) => { return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, FormFieldContext.Provider, { value: { name: props.name }, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _reacthookform.Controller, { ...props }) }); }; var useFormField = () => { const fieldContext = React.useContext(FormFieldContext); const itemContext = React.useContext(FormItemContext); const { getFieldState } = _reacthookform.useFormContext.call(void 0, ); const formState = _reacthookform.useFormState.call(void 0, { name: fieldContext.name }); const fieldState = getFieldState(fieldContext.name, formState); if (!fieldContext) { throw new Error("useFormField should be used within <FormField>"); } const { id } = itemContext; return { id, name: fieldContext.name, formItemId: `${id}-form-item`, formDescriptionId: `${id}-form-item-description`, formMessageId: `${id}-form-item-message`, ...fieldState }; }; var FormItemContext = React.createContext( {} ); function FormItem({ className, ...props }) { const id = React.useId(); return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, FormItemContext.Provider, { value: { id }, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { "data-slot": "form-item", className: cn("grid gap-2", className), ...props } ) }); } function FormLabel({ className, ...props }) { const { error, formItemId } = useFormField(); return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Label, { "data-slot": "form-label", "data-error": !!error, className: cn("data-[error=true]:text-destructive", className), htmlFor: formItemId, ...props } ); } function FormControl({ ...props }) { const { error, formItemId, formDescriptionId, formMessageId } = useFormField(); return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _reactslot.Slot, { "data-slot": "form-control", id: formItemId, "aria-describedby": !error ? `${formDescriptionId}` : `${formDescriptionId} ${formMessageId}`, "aria-invalid": !!error, ...props } ); } function FormMessage({ className, ...props }) { const { error, formMessageId } = useFormField(); const body = error ? String(_nullishCoalesce(_optionalChain([error, 'optionalAccess', _7 => _7.message]), () => ( ""))) : props.children; if (!body) { return null; } return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { "data-slot": "form-message", id: formMessageId, className: cn("text-destructive text-sm", className), ...props, children: body } ); } // src/components/ui/select.tsx var _reactselect = require('@radix-ui/react-select'); var SelectPrimitive = _interopRequireWildcard(_reactselect); var Select = SelectPrimitive.Root; var SelectValue = SelectPrimitive.Value; var SelectTrigger = React2.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, SelectPrimitive.Trigger, { ref, className: cn( "flex h-9 w-full items-center justify-between whitespace-nowrap rounded-md border border-input bg-transparent px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-ring disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1", className ), ...props, children: [ children, /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SelectPrimitive.Icon, { asChild: true, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.ChevronDown, { className: "h-4 w-4 opacity-50" }) }) ] } )); SelectTrigger.displayName = SelectPrimitive.Trigger.displayName; var SelectScrollUpButton = React2.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SelectPrimitive.ScrollUpButton, { ref, className: cn( "flex cursor-default items-center justify-center py-1", className ), ...props, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.ChevronUp, { className: "h-4 w-4" }) } )); SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName; var SelectScrollDownButton = React2.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SelectPrimitive.ScrollDownButton, { ref, className: cn( "flex cursor-default items-center justify-center py-1", className ), ...props, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.ChevronDown, { className: "h-4 w-4" }) } )); SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName; var SelectContent = React2.forwardRef(({ className, children, position = "popper", ...props }, ref) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SelectPrimitive.Portal, { children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, SelectPrimitive.Content, { ref, className: cn( "relative z-50 max-h-96 min-w-[8rem] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2", position === "popper" && "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1", className ), position, ...props, children: [ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SelectScrollUpButton, {}), /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SelectPrimitive.Viewport, { className: cn( "p-1", position === "popper" && "h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]" ), children } ), /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SelectScrollDownButton, {}) ] } ) })); SelectContent.displayName = SelectPrimitive.Content.displayName; var SelectLabel = React2.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SelectPrimitive.Label, { ref, className: cn("px-2 py-1.5 text-sm font-semibold", className), ...props } )); SelectLabel.displayName = SelectPrimitive.Label.displayName; var SelectItem = React2.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, SelectPrimitive.Item, { ref, className: cn( "relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-2 pr-8 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50", className ), ...props, children: [ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "absolute right-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SelectPrimitive.ItemIndicator, { children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.Check, { className: "h-4 w-4" }) }) }), /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SelectPrimitive.ItemText, { children }) ] } )); SelectItem.displayName = SelectPrimitive.Item.displayName; var SelectSeparator = React2.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SelectPrimitive.Separator, { ref, className: cn("-mx-1 my-1 h-px bg-muted", className), ...props } )); SelectSeparator.displayName = SelectPrimitive.Separator.displayName; exports.authViewPaths = authViewPaths; exports.AuthUIContext = AuthUIContext; exports.AuthUIProvider = AuthUIProvider; exports.cn = cn; exports.isValidEmail = isValidEmail; exports.getLocalizedError = getLocalizedError; exports.getSearchParam = getSearchParam; exports.getAuthViewByPath = getAuthViewByPath; exports.Button = Button; exports.Input = Input; exports.Dialog = Dialog; exports.DialogClose = DialogClose; exports.DialogContent = DialogContent; exports.DialogHeader = DialogHeader; exports.DialogFooter = DialogFooter; exports.DialogTitle = DialogTitle; exports.DialogDescription = DialogDescription; exports.Label = Label; exports.Form = Form; exports.FormField = FormField; exports.FormItem = FormItem; exports.FormLabel = FormLabel; exports.FormControl = FormControl; exports.FormMessage = FormMessage; exports.Select = Select; exports.SelectValue = SelectValue; exports.SelectTrigger = SelectTrigger; exports.SelectContent = SelectContent; exports.SelectItem = SelectItem;