version-pill-react 1.0.0 โ 1.1.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.d.mts +87 -9
- package/dist/index.d.ts +87 -9
- package/dist/index.js +485 -44
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +482 -43
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -15
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.tsx"],"sourcesContent":["\"use client\";\n\nimport React, { useState, useEffect, useCallback } from \"react\";\nimport clsx from \"clsx\";\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport interface Version {\n id: string;\n version: string;\n type: \"major\" | \"minor\" | \"patch\";\n title: string;\n description?: string;\n emoji?: string;\n features?: string[];\n releaseDate: number;\n isActive: boolean;\n}\n\nexport interface VersionPillConfig {\n /** Your project slug from Version Pill dashboard */\n projectId: string;\n /** Version Pill API base URL (default: https://versionpill.com) */\n baseUrl?: string;\n}\n\nexport interface VersionPillProps extends VersionPillConfig {\n /** Position of the pill */\n position?: \"top-left\" | \"top-right\" | \"bottom-left\" | \"bottom-right\" | \"inline\";\n /** Custom class name */\n className?: string;\n /** Theme */\n theme?: \"light\" | \"dark\" | \"auto\";\n /** Show \"Powered by Version Pill\" branding */\n showBranding?: boolean;\n /** Accent color (hex) */\n accentColor?: string;\n /** Callback when a new version is detected */\n onNewVersion?: (version: Version) => void;\n}\n\nexport interface ChangelogProps extends VersionPillConfig {\n /** Max height in pixels */\n maxHeight?: number;\n /** Theme */\n theme?: \"light\" | \"dark\" | \"auto\";\n /** Custom class name */\n className?: string;\n}\n\nexport interface RoadmapProps extends VersionPillConfig {\n /** Max height in pixels */\n maxHeight?: number;\n /** Theme */\n theme?: \"light\" | \"dark\" | \"auto\";\n /** Custom class name */\n className?: string;\n}\n\n// =============================================================================\n// CONSTANTS\n// =============================================================================\n\nconst DEFAULT_BASE_URL = \"https://versionpill.com\";\n\n// =============================================================================\n// STYLES\n// =============================================================================\n\nconst styles = {\n pill: `\n inline-flex items-center gap-1.5 px-2.5 py-1\n text-xs font-medium rounded-full cursor-pointer\n transition-all duration-200 select-none\n border shadow-sm hover:shadow-md\n `,\n pillLight: `bg-white text-gray-700 border-gray-200 hover:border-gray-300`,\n pillDark: `bg-gray-900 text-gray-100 border-gray-700 hover:border-gray-600`,\n\n modal: `fixed inset-0 z-[99999] flex items-center justify-center p-4`,\n backdrop: `absolute inset-0 bg-black/50 backdrop-blur-sm`,\n panel: `relative w-full max-w-md max-h-[80vh] overflow-hidden rounded-xl shadow-2xl`,\n panelLight: `bg-white`,\n panelDark: `bg-gray-900`,\n\n header: `p-4 border-b flex items-center justify-between`,\n headerLight: `border-gray-100`,\n headerDark: `border-gray-800`,\n\n content: `p-4 overflow-y-auto max-h-[60vh]`,\n\n version: `mb-4 last:mb-0`,\n versionHeader: `flex items-center gap-2 mb-2`,\n versionTitle: `font-semibold`,\n versionBadge: `px-1.5 py-0.5 text-[10px] font-medium rounded`,\n versionFeatures: `space-y-1 mt-2`,\n versionFeature: `flex items-start gap-2 text-sm`,\n\n footer: `p-3 border-t flex items-center justify-between`,\n footerLight: `border-gray-100 bg-gray-50`,\n footerDark: `border-gray-800 bg-gray-950`,\n\n button: `px-3 py-1.5 text-xs font-medium rounded-lg transition-colors`,\n buttonPrimary: `bg-blue-600 text-white hover:bg-blue-700`,\n buttonSecondary: `text-gray-500 hover:text-gray-700`,\n\n branding: `text-[10px] opacity-40 flex items-center gap-1`,\n newDot: `w-2 h-2 rounded-full bg-green-500 animate-pulse`,\n\n iframe: `w-full border-0`,\n};\n\n// =============================================================================\n// HOOKS\n// =============================================================================\n\nfunction useTheme(theme: \"light\" | \"dark\" | \"auto\"): \"light\" | \"dark\" {\n const [resolved, setResolved] = useState<\"light\" | \"dark\">(\"light\");\n\n useEffect(() => {\n if (theme === \"auto\") {\n const isDark = window.matchMedia(\"(prefers-color-scheme: dark)\").matches;\n setResolved(isDark ? \"dark\" : \"light\");\n\n const listener = (e: MediaQueryListEvent) => setResolved(e.matches ? \"dark\" : \"light\");\n const mq = window.matchMedia(\"(prefers-color-scheme: dark)\");\n mq.addEventListener(\"change\", listener);\n return () => mq.removeEventListener(\"change\", listener);\n } else {\n setResolved(theme);\n }\n }, [theme]);\n\n return resolved;\n}\n\n// =============================================================================\n// VERSION PILL COMPONENT\n// =============================================================================\n\nexport function VersionPill({\n projectId,\n baseUrl = DEFAULT_BASE_URL,\n position = \"inline\",\n className,\n theme = \"auto\",\n showBranding = true,\n accentColor,\n onNewVersion,\n}: VersionPillProps) {\n const [versions, setVersions] = useState<Version[]>([]);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const [isOpen, setIsOpen] = useState(false);\n const [hasNewVersion, setHasNewVersion] = useState(false);\n\n const resolvedTheme = useTheme(theme);\n const isLight = resolvedTheme === \"light\";\n\n const fetchChangelog = useCallback(async () => {\n try {\n const response = await fetch(`${baseUrl}/api/changelog/${projectId}?limit=10`);\n if (!response.ok) throw new Error(\"Failed to fetch changelog\");\n\n const data = await response.json();\n setVersions(data);\n\n const storedVersion = localStorage.getItem(`vp_${projectId}_seen`);\n if (data.length > 0 && data[0].version !== storedVersion) {\n setHasNewVersion(true);\n onNewVersion?.(data[0]);\n }\n } catch (err: any) {\n setError(err.message);\n } finally {\n setLoading(false);\n }\n }, [projectId, baseUrl, onNewVersion]);\n\n useEffect(() => {\n fetchChangelog();\n }, [fetchChangelog]);\n\n const handleOpen = () => {\n setIsOpen(true);\n if (versions.length > 0) {\n localStorage.setItem(`vp_${projectId}_seen`, versions[0].version);\n setHasNewVersion(false);\n }\n };\n\n const currentVersion = versions[0];\n\n const positionStyles: Record<string, string> = {\n \"top-left\": \"fixed top-4 left-4 z-[9999]\",\n \"top-right\": \"fixed top-4 right-4 z-[9999]\",\n \"bottom-left\": \"fixed bottom-4 left-4 z-[9999]\",\n \"bottom-right\": \"fixed bottom-4 right-4 z-[9999]\",\n inline: \"\",\n };\n\n if (loading) {\n return (\n <div className={clsx(positionStyles[position], className)}>\n <div className={clsx(styles.pill, isLight ? styles.pillLight : styles.pillDark)}>\n <span className=\"opacity-50\">...</span>\n </div>\n </div>\n );\n }\n\n if (error || !currentVersion) return null;\n\n return (\n <>\n <div className={clsx(positionStyles[position], className)}>\n <button\n onClick={handleOpen}\n className={clsx(styles.pill, isLight ? styles.pillLight : styles.pillDark)}\n style={accentColor ? { borderColor: accentColor } : undefined}\n >\n {hasNewVersion && <span className={styles.newDot} />}\n <span>v{currentVersion.version}</span>\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <path d=\"M6 9l6 6 6-6\" />\n </svg>\n </button>\n </div>\n\n {isOpen && (\n <div className={styles.modal}>\n <div className={styles.backdrop} onClick={() => setIsOpen(false)} />\n <div className={clsx(styles.panel, isLight ? styles.panelLight : styles.panelDark)}>\n <div className={clsx(styles.header, isLight ? styles.headerLight : styles.headerDark)}>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-lg\">{currentVersion.emoji || \"โจ\"}</span>\n <div>\n <h2 className={clsx(\"font-semibold\", isLight ? \"text-gray-900\" : \"text-white\")}>What's New</h2>\n <p className={clsx(\"text-xs\", isLight ? \"text-gray-500\" : \"text-gray-400\")}>\n Latest updates\n </p>\n </div>\n </div>\n <button\n onClick={() => setIsOpen(false)}\n className={clsx(\"p-1 rounded hover:bg-gray-100\", !isLight && \"hover:bg-gray-800\")}\n >\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <path d=\"M18 6L6 18M6 6l12 12\" />\n </svg>\n </button>\n </div>\n\n <div className={styles.content}>\n {versions.slice(0, 5).map((version) => (\n <div key={version.id} className={styles.version}>\n <div className={styles.versionHeader}>\n <span className=\"text-lg\">{version.emoji || \"๐ฆ\"}</span>\n <span className={clsx(styles.versionTitle, isLight ? \"text-gray-900\" : \"text-white\")}>\n {version.title}\n </span>\n <span\n className={clsx(\n styles.versionBadge,\n version.type === \"major\" ? \"bg-purple-100 text-purple-700\" :\n version.type === \"minor\" ? \"bg-blue-100 text-blue-700\" :\n \"bg-gray-100 text-gray-700\"\n )}\n >\n {version.type}\n </span>\n </div>\n <div className={clsx(\"text-xs mb-2\", isLight ? \"text-gray-500\" : \"text-gray-400\")}>\n v{version.version} ยท {new Date(version.releaseDate).toLocaleDateString()}\n </div>\n {version.description && (\n <p className={clsx(\"text-sm mb-2\", isLight ? \"text-gray-600\" : \"text-gray-300\")}>\n {version.description}\n </p>\n )}\n {version.features && version.features.length > 0 && (\n <ul className={styles.versionFeatures}>\n {version.features.map((feature, i) => (\n <li key={i} className={clsx(styles.versionFeature, isLight ? \"text-gray-600\" : \"text-gray-300\")}>\n <span className=\"text-green-500 mt-0.5\">โ</span>\n {feature}\n </li>\n ))}\n </ul>\n )}\n </div>\n ))}\n </div>\n\n <div className={clsx(styles.footer, isLight ? styles.footerLight : styles.footerDark)}>\n {showBranding && (\n <a\n href=\"https://versionpill.com\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className={clsx(styles.branding, isLight ? \"text-gray-400\" : \"text-gray-500\")}\n >\n <span>Powered by Version Pill</span>\n </a>\n )}\n <div className=\"flex items-center gap-2\">\n <a\n href={`${baseUrl}/${projectId}/roadmap`}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className={clsx(styles.button, styles.buttonSecondary)}\n >\n ๐ก Roadmap\n </a>\n <a\n href={`${baseUrl}/${projectId}/changelog`}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className={clsx(styles.button, styles.buttonPrimary)}\n style={accentColor ? { backgroundColor: accentColor } : undefined}\n >\n View All\n </a>\n </div>\n </div>\n </div>\n </div>\n )}\n </>\n );\n}\n\n// =============================================================================\n// CHANGELOG EMBED COMPONENT\n// =============================================================================\n\nexport function Changelog({\n projectId,\n baseUrl = DEFAULT_BASE_URL,\n maxHeight = 600,\n theme = \"auto\",\n className,\n}: ChangelogProps) {\n const resolvedTheme = useTheme(theme);\n\n return (\n <iframe\n src={`${baseUrl}/embed/${projectId}/changelog?theme=${resolvedTheme}`}\n className={clsx(styles.iframe, className)}\n style={{ height: maxHeight }}\n title=\"Changelog\"\n />\n );\n}\n\n// =============================================================================\n// ROADMAP EMBED COMPONENT\n// =============================================================================\n\nexport function Roadmap({\n projectId,\n baseUrl = DEFAULT_BASE_URL,\n maxHeight = 800,\n theme = \"auto\",\n className,\n}: RoadmapProps) {\n const resolvedTheme = useTheme(theme);\n\n return (\n <iframe\n src={`${baseUrl}/embed/${projectId}/roadmap?theme=${resolvedTheme}`}\n className={clsx(styles.iframe, className)}\n style={{ height: maxHeight }}\n title=\"Roadmap\"\n />\n );\n}\n\n// =============================================================================\n// EXPORTS\n// =============================================================================\n\nexport default VersionPill;\n"],"mappings":"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","names":["clsx"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.tsx"],"sourcesContent":["\"use client\";\n\nimport React, { useState, useEffect, useCallback } from \"react\";\nimport clsx from \"clsx\";\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport interface Version {\n version: string;\n type: \"major\" | \"minor\" | \"patch\";\n title: string;\n description?: string | null;\n emoji?: string | null;\n features?: string[];\n date: string | number;\n tasks?: { title: string; type: string }[];\n}\n\nexport interface ProjectInfo {\n name: string;\n slug: string;\n icon?: string | null;\n currentVersion?: string | null;\n}\n\nexport interface ChangelogAPIResponse {\n project: ProjectInfo;\n changelog: Version[];\n}\n\nexport interface BadgeAPIResponse {\n version: string | null;\n name: string;\n slug: string;\n}\n\nexport interface VersionPillConfig {\n /** Your project slug from Version Pill dashboard */\n projectId: string;\n /** Version Pill API base URL (default: https://versionpill.com) */\n baseUrl?: string;\n}\n\nexport type BadgeStyle = \"dot\" | \"pill\" | \"minimal\" | \"glass\" | \"gradient\";\nexport type BadgeSize = \"sm\" | \"md\" | \"lg\";\n\nexport interface VersionPillProps extends VersionPillConfig {\n /** Position of the pill */\n position?: \"top-left\" | \"top-right\" | \"bottom-left\" | \"bottom-right\" | \"inline\";\n /** Custom class name */\n className?: string;\n /** Theme */\n theme?: \"light\" | \"dark\" | \"auto\";\n /** Badge style variant */\n style?: BadgeStyle;\n /** Badge size */\n size?: BadgeSize;\n /** Show \"Powered by Version Pill\" branding */\n showBranding?: boolean;\n /** Accent color */\n accent?: \"green\" | \"blue\" | \"purple\" | \"orange\" | \"neutral\";\n /** Callback when a new version is detected */\n onNewVersion?: (version: Version) => void;\n /** Callback when badge is clicked */\n onClick?: () => void;\n}\n\nexport interface ChangelogProps extends VersionPillConfig {\n /** Max height in pixels */\n maxHeight?: number;\n /** Theme */\n theme?: \"light\" | \"dark\" | \"auto\";\n /** Custom class name */\n className?: string;\n}\n\nexport interface RoadmapProps extends VersionPillConfig {\n /** Max height in pixels */\n maxHeight?: number;\n /** Theme */\n theme?: \"light\" | \"dark\" | \"auto\";\n /** Custom class name */\n className?: string;\n}\n\n// =============================================================================\n// CONSTANTS\n// =============================================================================\n\nconst DEFAULT_BASE_URL = \"https://www.versionpill.com\";\n\n// Accent color definitions\nconst ACCENT_COLORS = {\n green: {\n light: { bg: \"rgba(34,197,94,0.1)\", border: \"rgba(34,197,94,0.25)\", text: \"#16a34a\", dot: \"#22c55e\" },\n dark: { bg: \"rgba(34,197,94,0.15)\", border: \"rgba(34,197,94,0.3)\", text: \"#4ade80\", dot: \"#22c55e\" },\n },\n blue: {\n light: { bg: \"rgba(59,130,246,0.1)\", border: \"rgba(59,130,246,0.25)\", text: \"#2563eb\", dot: \"#3b82f6\" },\n dark: { bg: \"rgba(59,130,246,0.15)\", border: \"rgba(59,130,246,0.3)\", text: \"#60a5fa\", dot: \"#3b82f6\" },\n },\n purple: {\n light: { bg: \"rgba(147,51,234,0.1)\", border: \"rgba(147,51,234,0.25)\", text: \"#7c3aed\", dot: \"#a855f7\" },\n dark: { bg: \"rgba(147,51,234,0.15)\", border: \"rgba(147,51,234,0.3)\", text: \"#c084fc\", dot: \"#a855f7\" },\n },\n orange: {\n light: { bg: \"rgba(249,115,22,0.1)\", border: \"rgba(249,115,22,0.25)\", text: \"#ea580c\", dot: \"#f97316\" },\n dark: { bg: \"rgba(249,115,22,0.15)\", border: \"rgba(249,115,22,0.3)\", text: \"#fb923c\", dot: \"#f97316\" },\n },\n neutral: {\n light: { bg: \"rgba(0,0,0,0.05)\", border: \"rgba(0,0,0,0.1)\", text: \"#52525b\", dot: \"#71717a\" },\n dark: { bg: \"rgba(255,255,255,0.08)\", border: \"rgba(255,255,255,0.12)\", text: \"#a1a1aa\", dot: \"#71717a\" },\n },\n};\n\n// Size definitions\nconst SIZE_CONFIG = {\n sm: { height: 22, padding: \"0 8px\", gap: 4, font: 10, dotSize: 5 },\n md: { height: 26, padding: \"0 10px\", gap: 5, font: 11, dotSize: 6 },\n lg: { height: 30, padding: \"0 12px\", gap: 6, font: 12, dotSize: 7 },\n};\n\n// =============================================================================\n// STYLES\n// =============================================================================\n\nconst styles = {\n pill: `\n inline-flex items-center gap-1.5 px-2.5 py-1\n text-xs font-medium rounded-full cursor-pointer\n transition-all duration-200 select-none\n border shadow-sm hover:shadow-md\n `,\n pillLight: `bg-white text-gray-700 border-gray-200 hover:border-gray-300`,\n pillDark: `bg-gray-900 text-gray-100 border-gray-700 hover:border-gray-600`,\n\n modal: `fixed inset-0 z-[99999] flex items-center justify-center p-4`,\n backdrop: `absolute inset-0 bg-black/50 backdrop-blur-sm`,\n panel: `relative w-full max-w-md max-h-[80vh] overflow-hidden rounded-xl shadow-2xl`,\n panelLight: `bg-white`,\n panelDark: `bg-gray-900`,\n\n header: `p-4 border-b flex items-center justify-between`,\n headerLight: `border-gray-100`,\n headerDark: `border-gray-800`,\n\n content: `p-4 overflow-y-auto max-h-[60vh]`,\n\n version: `mb-4 last:mb-0`,\n versionHeader: `flex items-center gap-2 mb-2`,\n versionTitle: `font-semibold`,\n versionBadge: `px-1.5 py-0.5 text-[10px] font-medium rounded`,\n versionFeatures: `space-y-1 mt-2`,\n versionFeature: `flex items-start gap-2 text-sm`,\n\n footer: `p-3 border-t flex items-center justify-between`,\n footerLight: `border-gray-100 bg-gray-50`,\n footerDark: `border-gray-800 bg-gray-950`,\n\n button: `px-3 py-1.5 text-xs font-medium rounded-lg transition-colors`,\n buttonPrimary: `bg-blue-600 text-white hover:bg-blue-700`,\n buttonSecondary: `text-gray-500 hover:text-gray-700`,\n\n branding: `text-[10px] opacity-40 flex items-center gap-1`,\n newDot: `w-2 h-2 rounded-full bg-green-500 animate-pulse`,\n\n iframe: `w-full border-0`,\n};\n\n// =============================================================================\n// HOOKS\n// =============================================================================\n\nfunction useTheme(theme: \"light\" | \"dark\" | \"auto\"): \"light\" | \"dark\" {\n const [resolved, setResolved] = useState<\"light\" | \"dark\">(\"light\");\n\n useEffect(() => {\n if (theme === \"auto\") {\n const isDark = window.matchMedia(\"(prefers-color-scheme: dark)\").matches;\n setResolved(isDark ? \"dark\" : \"light\");\n\n const listener = (e: MediaQueryListEvent) => setResolved(e.matches ? \"dark\" : \"light\");\n const mq = window.matchMedia(\"(prefers-color-scheme: dark)\");\n mq.addEventListener(\"change\", listener);\n return () => mq.removeEventListener(\"change\", listener);\n } else {\n setResolved(theme);\n }\n }, [theme]);\n\n return resolved;\n}\n\n// =============================================================================\n// VERSION PILL COMPONENT\n// =============================================================================\n\nexport function VersionPill({\n projectId,\n baseUrl = DEFAULT_BASE_URL,\n position = \"inline\",\n className,\n theme = \"auto\",\n style = \"dot\",\n size = \"md\",\n showBranding = true,\n accent = \"green\",\n onNewVersion,\n onClick,\n}: VersionPillProps) {\n const [project, setProject] = useState<ProjectInfo | null>(null);\n const [versions, setVersions] = useState<Version[]>([]);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const [isOpen, setIsOpen] = useState(false);\n const [hasNewVersion, setHasNewVersion] = useState(false);\n\n const resolvedTheme = useTheme(theme);\n const isLight = resolvedTheme === \"light\";\n const colors = ACCENT_COLORS[accent][isLight ? \"light\" : \"dark\"];\n const sizeConfig = SIZE_CONFIG[size];\n\n // Fetch version from badge API (lightweight)\n const fetchVersion = useCallback(async () => {\n try {\n const response = await fetch(`${baseUrl}/api/badge/${projectId}`);\n if (!response.ok) throw new Error(\"Failed to fetch version\");\n\n const data: BadgeAPIResponse = await response.json();\n if (data.version) {\n setProject({ name: data.name, slug: data.slug, currentVersion: data.version });\n\n const storedVersion = localStorage.getItem(`vp_${projectId}_seen`);\n if (data.version !== storedVersion) {\n setHasNewVersion(true);\n }\n }\n } catch (err: any) {\n setError(err.message);\n } finally {\n setLoading(false);\n }\n }, [projectId, baseUrl]);\n\n // Fetch full changelog when modal opens\n const fetchChangelog = useCallback(async () => {\n try {\n const response = await fetch(`${baseUrl}/api/changelog/${projectId}?limit=10`);\n if (!response.ok) throw new Error(\"Failed to fetch changelog\");\n\n const data: ChangelogAPIResponse = await response.json();\n setVersions(data.changelog);\n setProject(data.project);\n\n if (data.changelog.length > 0) {\n const storedVersion = localStorage.getItem(`vp_${projectId}_seen`);\n if (data.changelog[0].version !== storedVersion) {\n setHasNewVersion(true);\n onNewVersion?.(data.changelog[0]);\n }\n }\n } catch (err: any) {\n console.error(\"Failed to fetch changelog:\", err);\n }\n }, [projectId, baseUrl, onNewVersion]);\n\n useEffect(() => {\n fetchVersion();\n }, [fetchVersion]);\n\n const handleOpen = () => {\n if (onClick) {\n onClick();\n return;\n }\n setIsOpen(true);\n fetchChangelog();\n if (project?.currentVersion) {\n localStorage.setItem(`vp_${projectId}_seen`, project.currentVersion);\n setHasNewVersion(false);\n }\n };\n\n const currentVersion = project?.currentVersion;\n\n const positionStyles: Record<string, string> = {\n \"top-left\": \"fixed top-4 left-4 z-[9999]\",\n \"top-right\": \"fixed top-4 right-4 z-[9999]\",\n \"bottom-left\": \"fixed bottom-4 left-4 z-[9999]\",\n \"bottom-right\": \"fixed bottom-4 right-4 z-[9999]\",\n inline: \"\",\n };\n\n // Loading state\n if (loading) {\n return (\n <div className={clsx(positionStyles[position], className)} style={{ display: \"inline-flex\" }}>\n <span\n style={{\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: sizeConfig.gap,\n height: sizeConfig.height,\n padding: sizeConfig.padding,\n fontSize: sizeConfig.font,\n fontFamily: \"ui-monospace, monospace\",\n fontWeight: 500,\n borderRadius: 999,\n background: colors.bg,\n border: `1px solid ${colors.border}`,\n color: colors.text,\n opacity: 0.6,\n }}\n >\n <span\n style={{\n width: sizeConfig.dotSize,\n height: sizeConfig.dotSize,\n borderRadius: \"50%\",\n background: colors.dot,\n opacity: 0.4,\n }}\n />\n <span style={{ width: 32, height: sizeConfig.font, background: colors.border, borderRadius: 2 }} />\n </span>\n </div>\n );\n }\n\n if (error || !currentVersion) return null;\n\n // Render badge based on style\n const renderBadge = () => {\n const baseButtonStyle: React.CSSProperties = {\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: sizeConfig.gap,\n height: sizeConfig.height,\n padding: sizeConfig.padding,\n fontSize: sizeConfig.font,\n fontFamily: \"ui-monospace, monospace\",\n fontWeight: 600,\n borderRadius: 999,\n cursor: \"pointer\",\n border: \"none\",\n transition: \"all 150ms ease\",\n outline: \"none\",\n };\n\n switch (style) {\n case \"glass\":\n return (\n <button\n onClick={handleOpen}\n style={{\n ...baseButtonStyle,\n background: isLight ? \"rgba(255,255,255,0.7)\" : \"rgba(255,255,255,0.1)\",\n backdropFilter: \"blur(12px)\",\n WebkitBackdropFilter: \"blur(12px)\",\n border: `1px solid ${isLight ? \"rgba(255,255,255,0.8)\" : \"rgba(255,255,255,0.15)\"}`,\n boxShadow: \"0 4px 12px rgba(0,0,0,0.08), inset 0 1px 0 rgba(255,255,255,0.2)\",\n color: isLight ? \"#374151\" : \"#f3f4f6\",\n }}\n >\n {hasNewVersion && <PulseDot color={colors.dot} size={sizeConfig.dotSize} />}\n <span>v{currentVersion}</span>\n </button>\n );\n\n case \"gradient\":\n return (\n <button\n onClick={handleOpen}\n style={{\n ...baseButtonStyle,\n background: \"linear-gradient(135deg, #22c55e 0%, #16a34a 100%)\",\n color: \"#fff\",\n boxShadow: \"0 4px 12px rgba(34,197,94,0.3)\",\n }}\n >\n {hasNewVersion && <PulseDot color=\"#fff\" size={sizeConfig.dotSize} />}\n <span>v{currentVersion}</span>\n </button>\n );\n\n case \"pill\":\n return (\n <button\n onClick={handleOpen}\n style={{\n ...baseButtonStyle,\n background: colors.bg,\n border: `1px solid ${colors.border}`,\n color: colors.text,\n boxShadow: `0 0 0 0 ${colors.dot}`,\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.boxShadow = `0 0 12px 2px ${colors.dot}40`;\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.boxShadow = `0 0 0 0 ${colors.dot}`;\n }}\n >\n {hasNewVersion && <PulseDot color={colors.dot} size={sizeConfig.dotSize} />}\n <span>v{currentVersion}</span>\n </button>\n );\n\n case \"minimal\":\n return (\n <button\n onClick={handleOpen}\n style={{\n ...baseButtonStyle,\n background: \"transparent\",\n padding: 0,\n height: \"auto\",\n color: colors.text,\n }}\n >\n {hasNewVersion && <PulseDot color={colors.dot} size={sizeConfig.dotSize} />}\n <span>v{currentVersion}</span>\n </button>\n );\n\n case \"dot\":\n default:\n return (\n <button\n onClick={handleOpen}\n style={{\n ...baseButtonStyle,\n background: colors.bg,\n border: `1px solid ${colors.border}`,\n color: colors.text,\n }}\n >\n <span\n style={{\n width: sizeConfig.dotSize,\n height: sizeConfig.dotSize,\n borderRadius: \"50%\",\n background: colors.dot,\n flexShrink: 0,\n }}\n />\n <span>v{currentVersion}</span>\n </button>\n );\n }\n };\n\n return (\n <>\n <div className={clsx(positionStyles[position], className)} style={{ display: \"inline-flex\" }}>\n {renderBadge()}\n </div>\n\n {isOpen && (\n <div className={styles.modal}>\n <div className={styles.backdrop} onClick={() => setIsOpen(false)} />\n <div className={clsx(styles.panel, isLight ? styles.panelLight : styles.panelDark)}>\n <div className={clsx(styles.header, isLight ? styles.headerLight : styles.headerDark)}>\n <div style={{ display: \"flex\", alignItems: \"center\", gap: 10 }}>\n {project?.icon && <span style={{ fontSize: 20 }}>{project.icon}</span>}\n <div>\n <h2 className={clsx(\"font-semibold\", isLight ? \"text-gray-900\" : \"text-white\")}>\n {project?.name || \"What's New\"}\n </h2>\n <p className={clsx(\"text-xs\", isLight ? \"text-gray-500\" : \"text-gray-400\")}>\n Latest updates\n </p>\n </div>\n </div>\n <button\n onClick={() => setIsOpen(false)}\n className={clsx(\"p-1 rounded hover:bg-gray-100\", !isLight && \"hover:bg-gray-800\")}\n style={{ background: \"transparent\", border: \"none\", cursor: \"pointer\", color: isLight ? \"#374151\" : \"#9ca3af\" }}\n >\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <path d=\"M18 6L6 18M6 6l12 12\" />\n </svg>\n </button>\n </div>\n\n <div className={styles.content}>\n {versions.length === 0 ? (\n <div style={{ textAlign: \"center\", padding: 40, color: isLight ? \"#6b7280\" : \"#9ca3af\" }}>\n <div style={{ fontSize: 32, marginBottom: 8 }}>๐</div>\n <div>No releases yet</div>\n </div>\n ) : (\n versions.slice(0, 5).map((version, idx) => (\n <div key={idx} className={styles.version}>\n <div className={styles.versionHeader}>\n <span style={{ fontSize: 16 }}>{version.emoji || \"๐ฆ\"}</span>\n <span className={clsx(styles.versionTitle, isLight ? \"text-gray-900\" : \"text-white\")}>\n {version.title}\n </span>\n <span\n className={clsx(\n styles.versionBadge,\n version.type === \"major\" ? \"bg-purple-100 text-purple-700\" :\n version.type === \"minor\" ? \"bg-blue-100 text-blue-700\" :\n \"bg-gray-100 text-gray-700\"\n )}\n >\n {version.type}\n </span>\n </div>\n <div className={clsx(\"text-xs mb-2\", isLight ? \"text-gray-500\" : \"text-gray-400\")}>\n v{version.version} ยท {new Date(version.date).toLocaleDateString()}\n </div>\n {version.description && (\n <p className={clsx(\"text-sm mb-2\", isLight ? \"text-gray-600\" : \"text-gray-300\")}>\n {version.description}\n </p>\n )}\n {version.features && version.features.length > 0 && (\n <ul className={styles.versionFeatures}>\n {version.features.map((feature, i) => (\n <li key={i} className={clsx(styles.versionFeature, isLight ? \"text-gray-600\" : \"text-gray-300\")}>\n <span style={{ color: \"#22c55e\", marginTop: 2 }}>โ</span>\n {feature}\n </li>\n ))}\n </ul>\n )}\n </div>\n ))\n )}\n </div>\n\n <div className={clsx(styles.footer, isLight ? styles.footerLight : styles.footerDark)}>\n {showBranding && (\n <a\n href=\"https://versionpill.com\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className={clsx(styles.branding, isLight ? \"text-gray-400\" : \"text-gray-500\")}\n >\n <span>Powered by Version Pill</span>\n </a>\n )}\n <div style={{ display: \"flex\", alignItems: \"center\", gap: 8 }}>\n <a\n href={`${baseUrl}/${projectId}/roadmap`}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className={clsx(styles.button, styles.buttonSecondary)}\n >\n ๐ก Roadmap\n </a>\n <a\n href={`${baseUrl}/${projectId}/changelog`}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className={clsx(styles.button, styles.buttonPrimary)}\n >\n View All\n </a>\n </div>\n </div>\n </div>\n </div>\n )}\n </>\n );\n}\n\n// Pulsing dot indicator for new versions\nfunction PulseDot({ color, size }: { color: string; size: number }) {\n return (\n <span style={{ position: \"relative\", display: \"inline-flex\", width: size, height: size }}>\n <span\n style={{\n position: \"absolute\",\n inset: 0,\n borderRadius: \"50%\",\n background: color,\n opacity: 0.75,\n animation: \"vp-ping 1s cubic-bezier(0, 0, 0.2, 1) infinite\",\n }}\n />\n <span\n style={{\n position: \"relative\",\n display: \"inline-flex\",\n width: size,\n height: size,\n borderRadius: \"50%\",\n background: color,\n }}\n />\n <style>{`@keyframes vp-ping { 75%, 100% { transform: scale(2); opacity: 0; } }`}</style>\n </span>\n );\n}\n\n// =============================================================================\n// BADGE-ONLY COMPONENT (No Modal)\n// =============================================================================\n\nexport interface VersionBadgeProps {\n /** Your project slug from Version Pill dashboard */\n projectId: string;\n /** Version Pill API base URL (default: https://versionpill.com) */\n baseUrl?: string;\n /** Theme */\n theme?: \"light\" | \"dark\" | \"auto\";\n /** Badge style variant */\n style?: BadgeStyle;\n /** Badge size */\n size?: BadgeSize;\n /** Accent color */\n accent?: \"green\" | \"blue\" | \"purple\" | \"orange\" | \"neutral\";\n /** Custom class name */\n className?: string;\n /** Link to changelog (if provided, badge becomes a link) */\n href?: string;\n}\n\nexport function VersionBadge({\n projectId,\n baseUrl = DEFAULT_BASE_URL,\n theme = \"auto\",\n style = \"dot\",\n size = \"md\",\n accent = \"green\",\n className,\n href,\n}: VersionBadgeProps) {\n const [version, setVersion] = useState<string | null>(null);\n const [loading, setLoading] = useState(true);\n\n const resolvedTheme = useTheme(theme);\n const isLight = resolvedTheme === \"light\";\n const colors = ACCENT_COLORS[accent][isLight ? \"light\" : \"dark\"];\n const sizeConfig = SIZE_CONFIG[size];\n\n useEffect(() => {\n fetch(`${baseUrl}/api/badge/${projectId}`)\n .then((res) => res.json())\n .then((data) => setVersion(data.version))\n .catch(() => setVersion(null))\n .finally(() => setLoading(false));\n }, [projectId, baseUrl]);\n\n if (loading) {\n return (\n <span\n className={className}\n style={{\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: sizeConfig.gap,\n height: sizeConfig.height,\n padding: sizeConfig.padding,\n fontSize: sizeConfig.font,\n fontFamily: \"ui-monospace, monospace\",\n fontWeight: 500,\n borderRadius: 999,\n background: colors.bg,\n border: `1px solid ${colors.border}`,\n color: colors.text,\n opacity: 0.6,\n }}\n >\n <span\n style={{\n width: sizeConfig.dotSize,\n height: sizeConfig.dotSize,\n borderRadius: \"50%\",\n background: colors.dot,\n opacity: 0.4,\n }}\n />\n <span style={{ width: 32, height: sizeConfig.font, background: colors.border, borderRadius: 2 }} />\n </span>\n );\n }\n\n if (!version) return null;\n\n // Build style based on variant\n const getStyleVariant = (): React.CSSProperties => {\n const base: React.CSSProperties = {\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: sizeConfig.gap,\n fontSize: sizeConfig.font,\n fontFamily: \"ui-monospace, monospace\",\n fontWeight: 600,\n borderRadius: 999,\n textDecoration: \"none\",\n transition: \"opacity 150ms ease\",\n };\n\n if (style === \"minimal\") {\n return { ...base, background: \"transparent\", border: \"none\", padding: 0, color: colors.text };\n }\n if (style === \"glass\") {\n return {\n ...base,\n height: sizeConfig.height,\n padding: sizeConfig.padding,\n background: isLight ? \"rgba(255,255,255,0.7)\" : \"rgba(255,255,255,0.1)\",\n backdropFilter: \"blur(12px)\",\n WebkitBackdropFilter: \"blur(12px)\",\n border: `1px solid ${isLight ? \"rgba(255,255,255,0.8)\" : \"rgba(255,255,255,0.15)\"}`,\n boxShadow: \"0 4px 12px rgba(0,0,0,0.08), inset 0 1px 0 rgba(255,255,255,0.2)\",\n color: isLight ? \"#374151\" : \"#f3f4f6\",\n };\n }\n if (style === \"gradient\") {\n return {\n ...base,\n height: sizeConfig.height,\n padding: sizeConfig.padding,\n background: \"linear-gradient(135deg, #22c55e 0%, #16a34a 100%)\",\n border: \"none\",\n color: \"#fff\",\n boxShadow: \"0 4px 12px rgba(34,197,94,0.3)\",\n };\n }\n // Default (dot, pill)\n return {\n ...base,\n height: sizeConfig.height,\n padding: sizeConfig.padding,\n background: colors.bg,\n border: `1px solid ${colors.border}`,\n color: colors.text,\n };\n };\n\n const badgeStyle = getStyleVariant();\n\n const content = (\n <>\n {style === \"dot\" && (\n <span\n style={{\n width: sizeConfig.dotSize,\n height: sizeConfig.dotSize,\n borderRadius: \"50%\",\n background: colors.dot,\n flexShrink: 0,\n }}\n />\n )}\n <span>v{version}</span>\n </>\n );\n\n if (href) {\n return (\n <a\n href={href}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className={className}\n style={badgeStyle}\n onMouseEnter={(e) => (e.currentTarget.style.opacity = \"0.8\")}\n onMouseLeave={(e) => (e.currentTarget.style.opacity = \"1\")}\n >\n {content}\n </a>\n );\n }\n\n return (\n <span className={className} style={badgeStyle}>\n {content}\n </span>\n );\n}\n\n// =============================================================================\n// CHANGELOG EMBED COMPONENT\n// =============================================================================\n\nexport function Changelog({\n projectId,\n baseUrl = DEFAULT_BASE_URL,\n maxHeight = 600,\n theme = \"auto\",\n className,\n}: ChangelogProps) {\n const resolvedTheme = useTheme(theme);\n\n return (\n <iframe\n src={`${baseUrl}/embed/${projectId}/changelog?theme=${resolvedTheme}`}\n className={clsx(styles.iframe, className)}\n style={{ height: maxHeight }}\n title=\"Changelog\"\n />\n );\n}\n\n// =============================================================================\n// ROADMAP EMBED COMPONENT\n// =============================================================================\n\nexport function Roadmap({\n projectId,\n baseUrl = DEFAULT_BASE_URL,\n maxHeight = 800,\n theme = \"auto\",\n className,\n}: RoadmapProps) {\n const resolvedTheme = useTheme(theme);\n\n return (\n <iframe\n src={`${baseUrl}/embed/${projectId}/roadmap?theme=${resolvedTheme}`}\n className={clsx(styles.iframe, className)}\n style={{ height: maxHeight }}\n title=\"Roadmap\"\n />\n );\n}\n\n// =============================================================================\n// USE VERSION HOOK\n// =============================================================================\n\nexport interface UseVersionOptions {\n /** Your project slug from Version Pill dashboard */\n projectId: string;\n /** Version Pill API base URL (default: https://versionpill.com) */\n baseUrl?: string;\n /** Refetch interval in ms (0 = no refetch) */\n refetchInterval?: number;\n}\n\nexport interface UseVersionResult {\n /** Current version string (e.g., \"1.2.3\") */\n version: string | null;\n /** Project name */\n name: string | null;\n /** Project slug */\n slug: string | null;\n /** Loading state */\n loading: boolean;\n /** Error message if fetch failed */\n error: string | null;\n /** Manually refetch the version */\n refetch: () => Promise<void>;\n}\n\n// Simple in-memory cache to prevent flicker on re-renders\nconst versionCache: Record<string, { version: string | null; name: string | null; slug: string | null }> = {};\n\n/**\n * Hook to fetch the current version for a project.\n * Use this when you need the version data without the UI components.\n *\n * @example\n * ```tsx\n * const { version, loading } = useVersion({ projectId: \"my-app\" });\n * if (loading) return <Skeleton />;\n * return <span>v{version}</span>;\n * ```\n */\nexport function useVersion({\n projectId,\n baseUrl = DEFAULT_BASE_URL,\n refetchInterval = 0,\n}: UseVersionOptions): UseVersionResult {\n const cacheKey = `${baseUrl}:${projectId}`;\n const cached = versionCache[cacheKey];\n\n const [version, setVersion] = useState<string | null>(cached?.version ?? null);\n const [name, setName] = useState<string | null>(cached?.name ?? null);\n const [slug, setSlug] = useState<string | null>(cached?.slug ?? null);\n const [loading, setLoading] = useState(!cached);\n const [error, setError] = useState<string | null>(null);\n\n const fetchVersion = useCallback(async () => {\n // Skip fetch on server\n if (typeof window === 'undefined') return;\n\n try {\n setError(null);\n const response = await fetch(`${baseUrl}/api/badge/${projectId}`);\n if (!response.ok) throw new Error(\"Failed to fetch version\");\n\n const data: BadgeAPIResponse = await response.json();\n\n // Update cache\n versionCache[cacheKey] = { version: data.version, name: data.name, slug: data.slug };\n\n setVersion(data.version);\n setName(data.name);\n setSlug(data.slug);\n } catch (err: any) {\n setError(err.message);\n } finally {\n setLoading(false);\n }\n }, [projectId, baseUrl, cacheKey]);\n\n useEffect(() => {\n // Only fetch if not cached\n if (!cached) {\n fetchVersion();\n }\n }, [fetchVersion, cached]);\n\n useEffect(() => {\n if (refetchInterval > 0) {\n const interval = setInterval(fetchVersion, refetchInterval);\n return () => clearInterval(interval);\n }\n }, [refetchInterval, fetchVersion]);\n\n return { version, name, slug, loading, error, refetch: fetchVersion };\n}\n\n// =============================================================================\n// DEFAULT EXPORT\n// =============================================================================\n\nexport default VersionPill;\n"],"mappings":"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","names":["clsx"]}
|