"use client"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Switch } from "@/components/ui/switch"; import { cn } from "@/lib/utils"; import { CheckIcon, CopyIcon, EyeIcon, EyeOffIcon } from "lucide-react"; import type { ComponentProps, HTMLAttributes } from "react"; import { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState, } from "react"; interface EnvironmentVariablesContextType { showValues: boolean; setShowValues: (show: boolean) => void; } // Default noop for context default value // oxlint-disable-next-line eslint(no-empty-function) const noop = () => {}; const EnvironmentVariablesContext = createContext({ setShowValues: noop, showValues: false, }); export type EnvironmentVariablesProps = HTMLAttributes & { showValues?: boolean; defaultShowValues?: boolean; onShowValuesChange?: (show: boolean) => void; }; export const EnvironmentVariables = ({ showValues: controlledShowValues, defaultShowValues = false, onShowValuesChange, className, children, ...props }: EnvironmentVariablesProps) => { const [internalShowValues, setInternalShowValues] = useState(defaultShowValues); const showValues = controlledShowValues ?? internalShowValues; const setShowValues = useCallback( (show: boolean) => { setInternalShowValues(show); onShowValuesChange?.(show); }, [onShowValuesChange] ); const contextValue = useMemo( () => ({ setShowValues, showValues }), [setShowValues, showValues] ); return (
{children}
); }; export type EnvironmentVariablesHeaderProps = HTMLAttributes; export const EnvironmentVariablesHeader = ({ className, children, ...props }: EnvironmentVariablesHeaderProps) => (
{children}
); export type EnvironmentVariablesTitleProps = HTMLAttributes; export const EnvironmentVariablesTitle = ({ className, children, ...props }: EnvironmentVariablesTitleProps) => (

{children ?? "Environment Variables"}

); export type EnvironmentVariablesToggleProps = ComponentProps; export const EnvironmentVariablesToggle = ({ className, ...props }: EnvironmentVariablesToggleProps) => { const { showValues, setShowValues } = useContext(EnvironmentVariablesContext); return (
{showValues ? : }
); }; export type EnvironmentVariablesContentProps = HTMLAttributes; export const EnvironmentVariablesContent = ({ className, children, ...props }: EnvironmentVariablesContentProps) => (
{children}
); interface EnvironmentVariableContextType { name: string; value: string; } const EnvironmentVariableContext = createContext({ name: "", value: "", }); export type EnvironmentVariableGroupProps = HTMLAttributes; export const EnvironmentVariableGroup = ({ className, children, ...props }: EnvironmentVariableGroupProps) => (
{children}
); export type EnvironmentVariableNameProps = HTMLAttributes; export const EnvironmentVariableName = ({ className, children, ...props }: EnvironmentVariableNameProps) => { const { name } = useContext(EnvironmentVariableContext); return ( {children ?? name} ); }; export type EnvironmentVariableValueProps = HTMLAttributes; export const EnvironmentVariableValue = ({ className, children, ...props }: EnvironmentVariableValueProps) => { const { value } = useContext(EnvironmentVariableContext); const { showValues } = useContext(EnvironmentVariablesContext); const displayValue = showValues ? value : "•".repeat(Math.min(value.length, 20)); return ( {children ?? displayValue} ); }; export type EnvironmentVariableProps = HTMLAttributes & { name: string; value: string; }; export const EnvironmentVariable = ({ name, value, className, children, ...props }: EnvironmentVariableProps) => { const envVarContextValue = useMemo(() => ({ name, value }), [name, value]); return (
{children ?? ( <>
)}
); }; export type EnvironmentVariableCopyButtonProps = ComponentProps< typeof Button > & { onCopy?: () => void; onError?: (error: Error) => void; timeout?: number; copyFormat?: "name" | "value" | "export"; }; export const EnvironmentVariableCopyButton = ({ onCopy, onError, timeout = 2000, copyFormat = "value", children, className, ...props }: EnvironmentVariableCopyButtonProps) => { const [isCopied, setIsCopied] = useState(false); const timeoutRef = useRef(0); const { name, value } = useContext(EnvironmentVariableContext); const getTextToCopy = useCallback((): string => { const formatMap = { export: () => `export ${name}="${value}"`, name: () => name, value: () => value, }; return formatMap[copyFormat](); }, [name, value, copyFormat]); const copyToClipboard = useCallback(async () => { if (typeof window === "undefined" || !navigator?.clipboard?.writeText) { onError?.(new Error("Clipboard API not available")); return; } try { await navigator.clipboard.writeText(getTextToCopy()); setIsCopied(true); onCopy?.(); timeoutRef.current = window.setTimeout(() => setIsCopied(false), timeout); } catch (error) { onError?.(error as Error); } }, [getTextToCopy, onCopy, onError, timeout]); useEffect( () => () => { window.clearTimeout(timeoutRef.current); }, [] ); const Icon = isCopied ? CheckIcon : CopyIcon; return ( ); }; export type EnvironmentVariableRequiredProps = ComponentProps; export const EnvironmentVariableRequired = ({ className, children, ...props }: EnvironmentVariableRequiredProps) => ( {children ?? "Required"} );