UNPKG

@tanstack/devtools

Version:

TanStack Devtools is a set of tools for building advanced devtools for your application.

1,761 lines (1,728 loc) 160 kB
import { PLUGIN_TITLE_CONTAINER_ID, PLUGIN_CONTAINER_ID } from '../chunk/A767CXXU.js'; import { usePiPWindow, TANSTACK_DEVTOOLS, getAllPermutations, DevtoolsContext, MAX_ACTIVE_PLUGINS, uppercaseFirstLetter } from '../chunk/NHLNWQXL.js'; import { keyboardModifiers } from '../chunk/HURJB5JH.js'; import { createComponent, Portal, ssr, ssrAttribute, escape, ssrStyleProperty, ssrStyle } from 'solid-js/web'; import { createContext, createSignal, createEffect, onCleanup, Show, createMemo, For, useContext, onMount } from 'solid-js'; import { createShortcut, useKeyDownList } from '@solid-primitives/keyboard'; import { ThemeContextProvider, MainPanel as MainPanel$1, Section, SectionTitle, SectionIcon, SectionDescription, Checkbox, Select, Input, Button, ChevronDownIcon, CloseIcon, SearchIcon, SettingsIcon, PackageIcon, ExternalLinkIcon, CheckCircleIcon, XCircleIcon } from '@tanstack/devtools-ui'; import { devtoolsEventClient } from '@tanstack/devtools-client'; import clsx3 from 'clsx'; import * as goober from 'goober'; import { PiP, X, List, PageSearch, Cogs, SettingsCog, Link, Keyboard, GeoTag } from '@tanstack/devtools-ui/icons'; import { createStore } from 'solid-js/store'; import { createElementSize } from '@solid-primitives/resize-observer'; import { createEventListener } from '@solid-primitives/event-listener'; var useDraw = (props) => { const [activeHover, setActiveHover] = createSignal(false); const [forceExpand, setForceExpand] = createSignal(false); const expanded = createMemo(() => activeHover() || forceExpand()); let hoverTimeout = null; onCleanup(() => { if (hoverTimeout) clearTimeout(hoverTimeout); }); const hoverUtils = { enter: () => { if (hoverTimeout) { clearTimeout(hoverTimeout); hoverTimeout = null; } setActiveHover(true); }, leave: () => { hoverTimeout = setTimeout(() => { setActiveHover(false); }, props.animationMs); } }; return { expanded, setForceExpand, hoverUtils, animationMs: props.animationMs }; }; var DrawContext = createContext(void 0); var DrawClientProvider = (props) => { const value = useDraw({ animationMs: props.animationMs }); return createComponent(DrawContext.Provider, { value, get children() { return props.children; } }); }; function useDrawContext() { const context = useContext(DrawContext); if (context === void 0) { throw new Error(`useDrawContext must be used within a DrawClientProvider`); } return context; } // src/context/use-devtools-context.ts var useDevtoolsContext = () => { const context = useContext(DevtoolsContext); if (context === void 0) { throw new Error( "useDevtoolsShellContext must be used within a ShellContextProvider" ); } return context; }; function useTheme() { const { settings, setSettings } = useDevtoolsSettings(); const theme = createMemo(() => settings().theme); return { theme, setTheme: (theme2) => setSettings({ theme: theme2 }) }; } var usePlugins = () => { const { store, setStore } = useDevtoolsContext(); const { setForceExpand } = useDrawContext(); const plugins = createMemo(() => store.plugins); const activePlugins = createMemo(() => store.state.activePlugins); createEffect(() => { if (activePlugins().length === 0) { setForceExpand(true); } else { setForceExpand(false); } }); const toggleActivePlugins = (pluginId) => { setStore((prev) => { const isActive = prev.state.activePlugins.includes(pluginId); const currentPlugin = store.plugins?.find( (plugin) => plugin.id === pluginId ); if (currentPlugin?.destroy && isActive) { currentPlugin.destroy(pluginId); } const updatedPlugins = isActive ? prev.state.activePlugins.filter((id) => id !== pluginId) : [...prev.state.activePlugins, pluginId]; if (updatedPlugins.length > MAX_ACTIVE_PLUGINS) return prev; return { ...prev, state: { ...prev.state, activePlugins: updatedPlugins } }; }); }; return { plugins, toggleActivePlugins, activePlugins }; }; var useDevtoolsState = () => { const { store, setStore } = useDevtoolsContext(); const state = createMemo(() => store.state); const setState = (newState) => { setStore((prev) => ({ ...prev, state: { ...prev.state, ...newState } })); }; return { state, setState }; }; var useDevtoolsSettings = () => { const { store, setStore } = useDevtoolsContext(); const settings = createMemo(() => store.settings); const setSettings = (newSettings) => { setStore((prev) => ({ ...prev, settings: { ...prev.settings, ...newSettings } })); }; return { setSettings, settings }; }; var usePersistOpen = () => { const { state, setState } = useDevtoolsState(); const persistOpen = createMemo(() => state().persistOpen); const setPersistOpen = (value) => { setState({ persistOpen: value }); }; return { persistOpen, setPersistOpen }; }; var useHeight = () => { const { state, setState } = useDevtoolsState(); const height = createMemo(() => state().height); const setHeight = (newHeight) => { setState({ height: newHeight }); }; return { height, setHeight }; }; var recursivelyChangeTabIndex = (node, remove = true) => { if (remove) { node.setAttribute("tabIndex", "-1"); } else { node.removeAttribute("tabIndex"); } for (const child of node.children) { recursivelyChangeTabIndex(child, remove); } }; var useDisableTabbing = (isOpen) => { createEffect(() => { const el = document.getElementById(TANSTACK_DEVTOOLS); if (!el) return; recursivelyChangeTabIndex(el, !isOpen()); }); }; // src/utils/hotkey.ts var normalizeHotkey = (keys) => { if (!keys.includes("CtrlOrMeta")) { return [keys]; } return [ keys.map((key) => key === "CtrlOrMeta" ? "Control" : key), keys.map((key) => key === "CtrlOrMeta" ? "Meta" : key) ]; }; var getHotkeyPermutations = (hotkey) => { const normalizedHotkeys = normalizeHotkey(hotkey); return normalizedHotkeys.flatMap((normalizedHotkey) => { const modifiers = normalizedHotkey.filter( (key) => keyboardModifiers.includes(key) ); const nonModifiers = normalizedHotkey.filter( (key) => !keyboardModifiers.includes(key) ); if (modifiers.length === 0) { return [nonModifiers]; } const allModifierCombinations = getAllPermutations(modifiers); return allModifierCombinations.map((combo) => [...combo, ...nonModifiers]); }); }; var isHotkeyCombinationPressed = (keys, hotkey) => { const permutations = getHotkeyPermutations(hotkey); const pressedKeys = keys.map((key) => key.toUpperCase()); return permutations.some( (combo) => ( // every key in the combo must be pressed combo.every((key) => pressedKeys.includes(String(key).toUpperCase())) && // and no extra keys beyond the combo pressedKeys.every( (key) => combo.map((k) => String(k).toUpperCase()).includes(key) ) ) ); }; // src/styles/tokens.ts var tokens = { colors: { inherit: "inherit", current: "currentColor", transparent: "transparent", black: "#000000", white: "#ffffff", neutral: { 50: "#f9fafb", 100: "#f2f4f7", 200: "#eaecf0", 300: "#d0d5dd", 400: "#98a2b3", 500: "#667085", 600: "#475467", 700: "#344054", 800: "#1d2939", 900: "#101828" }, darkGray: { 50: "#525c7a", 100: "#49536e", 200: "#414962", 300: "#394056", 400: "#313749", 500: "#292e3d", 600: "#212530", 700: "#191c24", 800: "#111318", 900: "#0b0d10" }, gray: { 50: "#f9fafb", 100: "#f2f4f7", 200: "#eaecf0", 300: "#d0d5dd", 400: "#98a2b3", 500: "#667085", 600: "#475467", 700: "#344054", 800: "#1d2939", 900: "#101828" }, blue: { 25: "#F5FAFF", 50: "#EFF8FF", 100: "#D1E9FF", 200: "#B2DDFF", 300: "#84CAFF", 400: "#53B1FD", 500: "#2E90FA", 600: "#1570EF", 700: "#175CD3", 800: "#1849A9", 900: "#194185" }, green: { 25: "#F6FEF9", 50: "#ECFDF3", 100: "#D1FADF", 200: "#A6F4C5", 300: "#6CE9A6", 400: "#32D583", 500: "#12B76A", 600: "#039855", 700: "#027A48", 800: "#05603A", 900: "#054F31" }, red: { 50: "#fef2f2", 100: "#fee2e2", 200: "#fecaca", 300: "#fca5a5", 400: "#f87171", 500: "#ef4444", 600: "#dc2626", 700: "#b91c1c", 800: "#991b1b", 900: "#7f1d1d", 950: "#450a0a" }, yellow: { 25: "#FFFCF5", 50: "#FFFAEB", 100: "#FEF0C7", 200: "#FEDF89", 300: "#FEC84B", 400: "#FDB022", 500: "#F79009", 600: "#DC6803", 700: "#B54708", 800: "#93370D", 900: "#7A2E0E" }, purple: { 25: "#FAFAFF", 50: "#F4F3FF", 100: "#EBE9FE", 200: "#D9D6FE", 300: "#BDB4FE", 400: "#9B8AFB", 500: "#7A5AF8", 600: "#6938EF", 700: "#5925DC", 800: "#4A1FB8", 900: "#3E1C96" }, teal: { 25: "#F6FEFC", 50: "#F0FDF9", 100: "#CCFBEF", 200: "#99F6E0", 300: "#5FE9D0", 400: "#2ED3B7", 500: "#15B79E", 600: "#0E9384", 700: "#107569", 800: "#125D56", 900: "#134E48" }, pink: { 25: "#fdf2f8", 50: "#fce7f3", 100: "#fbcfe8", 200: "#f9a8d4", 300: "#f472b6", 400: "#ec4899", 500: "#db2777", 600: "#be185d", 700: "#9d174d", 800: "#831843", 900: "#500724" }, cyan: { 25: "#ecfeff", 50: "#cffafe", 100: "#a5f3fc", 200: "#67e8f9", 300: "#22d3ee", 400: "#06b6d4", 500: "#0891b2", 600: "#0e7490", 700: "#155e75", 800: "#164e63", 900: "#083344" } }, alpha: { 100: "ff", 90: "e5", 80: "cc", 70: "b3", 60: "99", 50: "80", 40: "66", 30: "4d", 20: "33", 10: "1a", 0: "00" }, font: { size: { "2xs": "calc(var(--tsrd-font-size) * 0.625)", xs: "calc(var(--tsrd-font-size) * 0.75)", sm: "calc(var(--tsrd-font-size) * 0.875)", md: "var(--tsrd-font-size)", lg: "calc(var(--tsrd-font-size) * 1.125)", xl: "calc(var(--tsrd-font-size) * 1.25)", "2xl": "calc(var(--tsrd-font-size) * 1.5)", "3xl": "calc(var(--tsrd-font-size) * 1.875)", "4xl": "calc(var(--tsrd-font-size) * 2.25)", "5xl": "calc(var(--tsrd-font-size) * 3)", "6xl": "calc(var(--tsrd-font-size) * 3.75)", "7xl": "calc(var(--tsrd-font-size) * 4.5)", "8xl": "calc(var(--tsrd-font-size) * 6)", "9xl": "calc(var(--tsrd-font-size) * 8)" }, lineHeight: { "3xs": "calc(var(--tsrd-font-size) * 0.75)", "2xs": "calc(var(--tsrd-font-size) * 0.875)", xs: "calc(var(--tsrd-font-size) * 1)", sm: "calc(var(--tsrd-font-size) * 1.25)", md: "calc(var(--tsrd-font-size) * 1.5)", lg: "calc(var(--tsrd-font-size) * 1.75)", xl: "calc(var(--tsrd-font-size) * 2)", "2xl": "calc(var(--tsrd-font-size) * 2.25)", "3xl": "calc(var(--tsrd-font-size) * 2.5)", "4xl": "calc(var(--tsrd-font-size) * 2.75)", "5xl": "calc(var(--tsrd-font-size) * 3)", "6xl": "calc(var(--tsrd-font-size) * 3.25)", "7xl": "calc(var(--tsrd-font-size) * 3.5)", "8xl": "calc(var(--tsrd-font-size) * 3.75)", "9xl": "calc(var(--tsrd-font-size) * 4)" }, weight: { thin: "100", extralight: "200", light: "300", normal: "400", medium: "500", semibold: "600", bold: "700", extrabold: "800", black: "900" }, fontFamily: { sans: "ui-sans-serif, Inter, system-ui, sans-serif, sans-serif", mono: `ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace` } }, breakpoints: { xs: "320px", sm: "640px", md: "768px", lg: "1024px", xl: "1280px", "2xl": "1536px" }, border: { radius: { none: "0px", xs: "calc(var(--tsrd-font-size) * 0.125)", sm: "calc(var(--tsrd-font-size) * 0.25)", md: "calc(var(--tsrd-font-size) * 0.375)", lg: "calc(var(--tsrd-font-size) * 0.5)", xl: "calc(var(--tsrd-font-size) * 0.75)", "2xl": "calc(var(--tsrd-font-size) * 1)", "3xl": "calc(var(--tsrd-font-size) * 1.5)", full: "9999px" } }, size: { 0: "0px", 0.25: "calc(var(--tsrd-font-size) * 0.0625)", 0.5: "calc(var(--tsrd-font-size) * 0.125)", 1: "calc(var(--tsrd-font-size) * 0.25)", 1.5: "calc(var(--tsrd-font-size) * 0.375)", 2: "calc(var(--tsrd-font-size) * 0.5)", 2.5: "calc(var(--tsrd-font-size) * 0.625)", 3: "calc(var(--tsrd-font-size) * 0.75)", 3.5: "calc(var(--tsrd-font-size) * 0.875)", 4: "calc(var(--tsrd-font-size) * 1)", 4.5: "calc(var(--tsrd-font-size) * 1.125)", 5: "calc(var(--tsrd-font-size) * 1.25)", 5.5: "calc(var(--tsrd-font-size) * 1.375)", 6: "calc(var(--tsrd-font-size) * 1.5)", 6.5: "calc(var(--tsrd-font-size) * 1.625)", 7: "calc(var(--tsrd-font-size) * 1.75)", 8: "calc(var(--tsrd-font-size) * 2)", 9: "calc(var(--tsrd-font-size) * 2.25)", 10: "calc(var(--tsrd-font-size) * 2.5)", 11: "calc(var(--tsrd-font-size) * 2.75)", 12: "calc(var(--tsrd-font-size) * 3)", 14: "calc(var(--tsrd-font-size) * 3.5)", 16: "calc(var(--tsrd-font-size) * 4)", 20: "calc(var(--tsrd-font-size) * 5)", 24: "calc(var(--tsrd-font-size) * 6)", 28: "calc(var(--tsrd-font-size) * 7)", 32: "calc(var(--tsrd-font-size) * 8)", 36: "calc(var(--tsrd-font-size) * 9)", 40: "calc(var(--tsrd-font-size) * 10)", 44: "calc(var(--tsrd-font-size) * 11)", 48: "calc(var(--tsrd-font-size) * 12)", 52: "calc(var(--tsrd-font-size) * 13)", 56: "calc(var(--tsrd-font-size) * 14)", 60: "calc(var(--tsrd-font-size) * 15)", 64: "calc(var(--tsrd-font-size) * 16)", 72: "calc(var(--tsrd-font-size) * 18)", 80: "calc(var(--tsrd-font-size) * 20)", 96: "calc(var(--tsrd-font-size) * 24)" }, shadow: { xs: (_ = "rgb(0 0 0 / 0.1)") => `0 1px 2px 0 rgb(0 0 0 / 0.05)`, sm: (color = "rgb(0 0 0 / 0.1)") => `0 1px 3px 0 ${color}, 0 1px 2px -1px ${color}`, md: (color = "rgb(0 0 0 / 0.1)") => `0 4px 6px -1px ${color}, 0 2px 4px -2px ${color}`, lg: (color = "rgb(0 0 0 / 0.1)") => `0 10px 15px -3px ${color}, 0 4px 6px -4px ${color}`, xl: (color = "rgb(0 0 0 / 0.1)") => `0 20px 25px -5px ${color}, 0 8px 10px -6px ${color}`, "2xl": (color = "rgb(0 0 0 / 0.25)") => `0 25px 50px -12px ${color}`, inner: (color = "rgb(0 0 0 / 0.05)") => `inset 0 2px 4px 0 ${color}`, none: () => `none` }, zIndices: { hide: -1, auto: "auto", base: 0, docked: 10, dropdown: 1e3, sticky: 1100, banner: 1200, overlay: 1300, modal: 1400, popover: 1500, skipLink: 1600, toast: 1700, tooltip: 1800 } }; // src/styles/use-styles.ts var mSecondsToCssSeconds = (mSeconds) => `${(mSeconds / 1e3).toFixed(2)}s`; var fadeIn = goober.keyframes` from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } `; var slideInRight = goober.keyframes` from { transform: translateX(100%); } to { transform: translateX(0); } `; var slideUp = goober.keyframes` from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } `; var statusFadeIn = goober.keyframes` from { opacity: 0; } to { opacity: 1; } `; var iconPop = goober.keyframes` 0% { transform: scale(0); } 50% { transform: scale(1.2); } 100% { transform: scale(1); } `; var spin = goober.keyframes` to { transform: rotate(360deg); } `; var sparkle = goober.keyframes` 0%, 100% { opacity: 1; transform: scale(1) rotate(0deg); } 50% { opacity: 0.6; transform: scale(1.1) rotate(10deg); } `; var stylesFactory = (theme) => { const { colors, font, size, border } = tokens; const { fontFamily, size: fontSize } = font; const css2 = goober.css; const t = (light, dark) => theme === "light" ? light : dark; return { seoTabContainer: css2` padding: 0; margin: 0 auto; background: ${t(colors.white, colors.darkGray[700])}; border-radius: 8px; box-shadow: none; overflow-y: auto; height: 100%; display: flex; flex-direction: column; gap: 0; width: 100%; overflow-y: auto; `, seoTabTitle: css2` font-size: 1.25rem; font-weight: 600; color: ${t(colors.gray[900], colors.gray[100])}; margin: 0; padding: 1rem 1.5rem 0.5rem 1.5rem; text-align: left; border-bottom: 1px solid ${t(colors.gray[200], colors.gray[800])}; `, seoTabSection: css2` padding: 1.5rem; background: ${t(colors.gray[50], colors.darkGray[800])}; border: 1px solid ${t(colors.gray[200], colors.gray[800])}; display: flex; flex-direction: column; gap: 0.5rem; margin-bottom: 2rem; border-radius: 0.75rem; `, seoSubNav: css2` display: flex; flex-direction: row; gap: 0; margin-bottom: 1rem; border-bottom: 1px solid ${t(colors.gray[200], colors.gray[800])}; `, seoSubNavLabel: css2` padding: 0.5rem 1rem; font-size: 0.875rem; font-weight: 500; color: ${t(colors.gray[600], colors.gray[400])}; background: none; border: none; border-bottom: 2px solid transparent; margin-bottom: -1px; cursor: pointer; font-family: inherit; &:hover { color: ${t(colors.gray[800], colors.gray[200])}; } `, seoSubNavLabelActive: css2` color: ${t(colors.gray[900], colors.gray[100])}; border-bottom-color: ${t(colors.gray[900], colors.gray[100])}; `, seoPreviewSection: css2` display: flex; flex-direction: row; gap: 16px; margin-bottom: 0; justify-content: flex-start; align-items: flex-start; overflow-x: auto; flex-wrap: wrap; padding-bottom: 0.5rem; `, seoPreviewCard: css2` border: 1px solid ${t(colors.gray[200], colors.gray[800])}; border-radius: 8px; padding: 12px 10px; background: ${t(colors.white, colors.darkGray[900])}; margin-bottom: 0; box-shadow: 0 1px 3px ${t("rgba(0,0,0,0.05)", "rgba(0,0,0,0.1)")}; display: flex; flex-direction: column; align-items: flex-start; min-width: 200px; max-width: 240px; font-size: 0.95rem; gap: 4px; `, seoPreviewHeader: css2` font-size: 0.875rem; font-weight: 600; margin-bottom: 0; color: ${t(colors.gray[700], colors.gray[300])}; `, seoPreviewImage: css2` max-width: 100%; border-radius: 6px; margin-bottom: 6px; box-shadow: 0 1px 2px ${t("rgba(0,0,0,0.03)", "rgba(0,0,0,0.06)")}; height: 160px; object-fit: cover; `, seoPreviewTitle: css2` font-size: 0.9rem; font-weight: 600; margin-bottom: 4px; color: ${t(colors.gray[900], colors.gray[100])}; `, seoPreviewDesc: css2` color: ${t(colors.gray[600], colors.gray[400])}; margin-bottom: 4px; font-size: 0.8rem; `, seoPreviewUrl: css2` color: ${t(colors.gray[500], colors.gray[500])}; font-size: 0.75rem; margin-bottom: 0; word-break: break-all; `, seoMissingTagsSection: css2` margin-top: 4px; font-size: 0.875rem; color: ${t(colors.red[500], colors.red[400])}; `, seoMissingTagsList: css2` margin: 4px 0 0 0; padding: 0; list-style: none; display: flex; flex-wrap: wrap; gap: 4px; max-width: 240px; `, seoMissingTag: css2` background: ${t(colors.red[100], colors.red[500] + "22")}; color: ${t(colors.red[700], colors.red[500])}; border-radius: 3px; padding: 2px 6px; font-size: 0.75rem; font-weight: 500; `, seoAllTagsFound: css2` color: ${t(colors.green[700], colors.green[500])}; font-weight: 500; margin-left: 0; padding: 0 10px 8px 10px; font-size: 0.875rem; `, serpPreviewBlock: css2` margin-bottom: 1.5rem; border: 1px solid ${t(colors.gray[200], colors.gray[700])}; border-radius: 10px; padding: 1rem; `, serpPreviewLabel: css2` font-size: 0.875rem; font-weight: 600; margin-bottom: 0.5rem; color: ${t(colors.gray[700], colors.gray[300])}; `, serpSnippet: css2` border: 1px solid ${t(colors.gray[100], colors.gray[800])}; border-radius: 8px; padding: 1rem 1.25rem; background: ${t(colors.white, colors.darkGray[900])}; max-width: 600px; font-family: ${fontFamily.sans}; box-shadow: 0 1px 2px ${t("rgba(0,0,0,0.04)", "rgba(0,0,0,0.08)")}; `, serpSnippetMobile: css2` border: 1px solid ${t(colors.gray[100], colors.gray[800])}; border-radius: 8px; padding: 1rem 1.25rem; background: ${t(colors.white, colors.darkGray[900])}; max-width: 380px; font-family: ${fontFamily.sans}; box-shadow: 0 1px 2px ${t("rgba(0,0,0,0.04)", "rgba(0,0,0,0.08)")}; `, serpSnippetDescMobile: css2` font-size: 0.875rem; color: ${t(colors.gray[700], colors.gray[300])}; margin: 0; line-height: 1.5; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; overflow: hidden; `, serpSnippetTopRow: css2` display: flex; align-items: center; gap: 12px; margin-bottom: 8px; `, serpSnippetFavicon: css2` width: 28px; height: 28px; border-radius: 50%; flex-shrink: 0; object-fit: contain; overflow: hidden; display: flex; align-items: center; justify-content: center; `, serpSnippetDefaultFavicon: css2` width: 28px; height: 28px; background-color: ${t(colors.gray[200], colors.gray[800])}; border-radius: 50%; flex-shrink: 0; object-fit: contain; overflow: hidden; display: flex; align-items: center; justify-content: center; `, serpSnippetSiteColumn: css2` display: flex; flex-direction: column; gap: 0; min-width: 0; `, serpSnippetSiteName: css2` font-size: 0.875rem; color: ${t(colors.gray[900], colors.gray[100])}; line-height: 1.4; margin: 0; `, serpSnippetSiteUrl: css2` font-size: 0.75rem; color: ${t(colors.gray[500], colors.gray[500])}; line-height: 1.4; margin: 0; `, serpSnippetTitle: css2` font-size: 1.25rem; font-weight: 400; color: ${t("#1a0dab", "#8ab4f8")}; margin: 0 0 4px 0; line-height: 1.3; `, serpSnippetDesc: css2` font-size: 0.875rem; color: ${t(colors.gray[700], colors.gray[300])}; margin: 0; line-height: 1.5; `, serpMeasureHidden: css2` position: absolute; left: -9999px; top: 0; visibility: hidden; pointer-events: none; box-sizing: border-box; `, serpMeasureHiddenMobile: css2` position: absolute; left: -9999px; top: 0; width: 340px; visibility: hidden; pointer-events: none; font-size: 0.875rem; line-height: 1.5; `, serpReportSection: css2` margin-top: 1rem; font-size: 0.875rem; color: ${t(colors.gray[700], colors.gray[300])}; `, serpErrorList: css2` margin: 4px 0 0 0; padding-left: 1.25rem; list-style-type: disc; `, serpReportItem: css2` margin-top: 0.25rem; color: ${t(colors.red[700], colors.red[400])}; font-size: 0.875rem; `, devtoolsPanelContainer: (panelLocation, isDetached) => css2` direction: ltr; position: fixed; overflow-y: hidden; overflow-x: hidden; ${panelLocation}: 0; right: 0; z-index: 99999; width: 100%; ${isDetached ? "" : "max-height: 90%;"} border-top: 1px solid ${t(colors.gray[200], colors.gray[800])}; transform-origin: top; `, devtoolsPanelContainerVisibility: (isOpen) => { return css2` visibility: ${isOpen ? "visible" : "hidden"}; height: ${isOpen ? "auto" : "0"}; `; }, devtoolsPanelContainerResizing: (isResizing) => { if (isResizing()) { return css2` transition: none; `; } return css2` transition: all 0.4s ease; `; }, devtoolsPanelContainerAnimation: (isOpen, height, panelLocation) => { if (isOpen) { return css2` pointer-events: auto; transform: translateY(0); `; } return css2` pointer-events: none; transform: translateY(${panelLocation === "top" ? -height : height}px); `; }, devtoolsPanel: css2` display: flex; font-size: ${fontSize.sm}; font-family: ${fontFamily.sans}; background-color: ${t(colors.white, colors.darkGray[700])}; color: ${t(colors.gray[900], colors.gray[300])}; width: w-screen; flex-direction: row; overflow-x: hidden; overflow-y: hidden; height: 100%; `, dragHandle: (panelLocation) => css2` position: absolute; left: 0; ${panelLocation === "bottom" ? "top" : "bottom"}: 0; width: 100%; height: 4px; cursor: row-resize; user-select: none; z-index: 100000; &:hover { background-color: ${t(colors.gray[400], colors.gray[500])}; } `, mainCloseBtn: css2` background: transparent; position: fixed; z-index: 99999; display: inline-flex; width: fit-content; cursor: pointer; appearance: none; border: 0; align-items: center; padding: 0; font-size: ${font.size.xs}; cursor: pointer; transition: all 0.25s ease-out; & > img { width: 56px; height: 56px; transition: all 0.3s ease; outline-offset: 2px; border-radius: ${border.radius.full}; outline: 2px solid transparent; } &:hide-until-hover { opacity: 0; pointer-events: none; visibility: hidden; } &:hide-until-hover:hover { opacity: 1; pointer-events: auto; visibility: visible; } & > img:focus-visible, img:hover { outline: 2px solid ${t(colors.black, colors.black)}; } `, mainCloseBtnPosition: (position) => { const base = css2` ${position === "top-left" ? `top: ${size[2]}; left: ${size[2]};` : ""} ${position === "top-right" ? `top: ${size[2]}; right: ${size[2]};` : ""} ${position === "middle-left" ? `top: 50%; left: ${size[2]}; transform: translateY(-50%);` : ""} ${position === "middle-right" ? `top: 50%; right: ${size[2]}; transform: translateY(-50%);` : ""} ${position === "bottom-left" ? `bottom: ${size[2]}; left: ${size[2]};` : ""} ${position === "bottom-right" ? `bottom: ${size[2]}; right: ${size[2]};` : ""} `; return base; }, mainCloseBtnAnimation: (isOpen, hideUntilHover) => { if (!isOpen) { return hideUntilHover ? css2` opacity: 0; &:hover { opacity: 1; pointer-events: auto; visibility: visible; } ` : css2` opacity: 1; pointer-events: auto; visibility: visible; `; } return css2` opacity: 0; pointer-events: none; visibility: hidden; `; }, tabContainer: css2` display: flex; flex-direction: column; align-items: center; justify-content: flex-start; height: 100%; background-color: ${t(colors.gray[50], colors.darkGray[900])}; border-right: 1px solid ${t(colors.gray[200], colors.gray[800])}; box-shadow: none; position: relative; width: ${size[10]}; `, tab: css2` display: flex; align-items: center; justify-content: center; width: 100%; height: ${size[10]}; cursor: pointer; font-size: ${fontSize.sm}; font-family: ${fontFamily.sans}; color: ${t(colors.gray[600], colors.gray[400])}; background-color: transparent; border: none; transition: all 0.15s ease; border-left: 2px solid transparent; &:hover:not(.close):not(.active):not(.detach) { background-color: ${t(colors.gray[100], colors.gray[800])}; color: ${t(colors.gray[900], colors.gray[100])}; border-left: 2px solid ${t(colors.gray[900], colors.gray[100])}; } &.active { background-color: ${t(colors.gray[100], colors.gray[800])}; color: ${t(colors.gray[900], colors.gray[100])}; border-left: 2px solid ${t(colors.gray[900], colors.gray[100])}; } &.detach { &:hover { background-color: ${t(colors.gray[100], colors.gray[800])}; } &:hover { color: ${t(colors.green[700], colors.green[500])}; } } &.close { margin-top: auto; &:hover { background-color: ${t(colors.gray[100], colors.gray[800])}; } &:hover { color: ${t(colors.red[700], colors.red[500])}; } } &.disabled { cursor: not-allowed; opacity: 0.2; pointer-events: none; } &.disabled:hover { background-color: transparent; color: ${colors.gray[300]}; } & > svg { flex-shrink: 0; } `, tabContent: css2` transition: all 0.2s ease-in-out; width: 100%; height: 100%; `, pluginsTabPanel: css2` display: flex; flex-direction: row; width: 100%; height: 100%; overflow: hidden; `, pluginsTabDraw: (isExpanded) => css2` width: ${isExpanded ? size[48] : 0}; height: 100%; background-color: ${t(colors.white, colors.darkGray[900])}; box-shadow: none; ${isExpanded ? `border-right: 1px solid ${t(colors.gray[200], colors.gray[800])};` : ""} `, pluginsTabDrawExpanded: css2` width: ${size[48]}; border-right: 1px solid ${t(colors.gray[200], colors.gray[800])}; `, pluginsTabDrawTransition: (mSeconds) => { return css2` transition: width ${mSecondsToCssSeconds(mSeconds)} ease; `; }, pluginsTabSidebar: (isExpanded) => css2` width: ${size[48]}; overflow-y: auto; transform: ${isExpanded ? "translateX(0)" : "translateX(-100%)"}; display: flex; flex-direction: column; `, pluginsTabSidebarTransition: (mSeconds) => { return css2` transition: transform ${mSecondsToCssSeconds(mSeconds)} ease; `; }, pluginsList: css2` flex: 1; overflow-y: auto; `, pluginName: css2` font-size: ${fontSize.xs}; font-family: ${fontFamily.sans}; color: ${t(colors.gray[600], colors.gray[400])}; padding: ${size[2]}; cursor: pointer; text-align: center; transition: all 0.15s ease; border-left: 2px solid transparent; &:hover { background-color: ${t(colors.gray[100], colors.gray[800])}; color: ${t(colors.gray[900], colors.gray[100])}; padding: ${size[2]}; } &.active { background-color: ${t(colors.gray[100], colors.gray[800])}; color: ${t(colors.gray[900], colors.gray[100])}; border-left: 2px solid ${t(colors.gray[900], colors.gray[100])}; } &.active:hover { background-color: ${t(colors.gray[200], colors.gray[700])}; } `, pluginsTabContent: css2` width: 100%; height: 100%; min-width: 0; min-height: 0; & > * { min-width: 0; min-height: 0; width: 100%; height: 100%; } & > * > * { min-width: 0; min-height: 0; width: 100%; height: 100%; } &:not(:last-child) { border-right: 5px solid ${t(colors.purple[200], colors.purple[800])}; } `, settingsGroup: css2` display: flex; flex-direction: column; gap: 0.75rem; `, conditionalSetting: css2` margin-left: 1.5rem; padding-left: 1rem; border-left: 2px solid ${t(colors.gray[300], colors.gray[600])}; background-color: ${t(colors.gray[50], colors.darkGray[900])}; padding: 0.75rem; border-radius: 0.375rem; margin-top: 0.5rem; `, settingRow: css2` display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; @media (max-width: 768px) { grid-template-columns: 1fr; } `, settingsModifiers: css2` display: flex; gap: 0.5rem; `, settingsStack: css2` display: flex; flex-direction: column; gap: 1rem; `, // No Plugins Fallback Styles noPluginsFallback: css2` display: flex; align-items: center; justify-content: center; min-height: 400px; padding: 2rem; background: ${t(colors.gray[50], colors.darkGray[700])}; width: 100%; height: 100%; `, noPluginsFallbackContent: css2` max-width: 600px; text-align: center; display: flex; flex-direction: column; align-items: center; gap: 1rem; `, noPluginsFallbackIcon: css2` width: 64px; height: 64px; color: ${t(colors.gray[400], colors.gray[600])}; margin-bottom: 0.5rem; svg { width: 100%; height: 100%; } `, noPluginsFallbackTitle: css2` font-size: 1.5rem; font-weight: 600; color: ${t(colors.gray[900], colors.gray[100])}; margin: 0; `, noPluginsFallbackDescription: css2` font-size: 0.95rem; color: ${t(colors.gray[600], colors.gray[400])}; line-height: 1.5; margin: 0; `, noPluginsSuggestions: css2` width: 100%; margin-top: 1.5rem; padding: 1.5rem; background: ${t(colors.white, colors.darkGray[800])}; border: 1px solid ${t(colors.gray[200], colors.gray[700])}; border-radius: 0.5rem; `, noPluginsSuggestionsTitle: css2` font-size: 1.125rem; font-weight: 600; color: ${t(colors.gray[900], colors.gray[100])}; margin: 0 0 0.5rem 0; `, noPluginsSuggestionsDesc: css2` font-size: 0.875rem; color: ${t(colors.gray[600], colors.gray[400])}; margin: 0 0 1rem 0; `, noPluginsSuggestionsList: css2` display: flex; flex-direction: column; gap: 0.75rem; `, noPluginsSuggestionCard: css2` display: flex; align-items: center; justify-content: space-between; padding: 1rem; background: ${t(colors.gray[50], colors.darkGray[900])}; border: 1px solid ${t(colors.gray[200], colors.gray[700])}; border-radius: 0.375rem; transition: all 0.15s ease; &:hover { border-color: ${t(colors.gray[300], colors.gray[600])}; background: ${t(colors.gray[100], colors.darkGray[800])}; } `, noPluginsSuggestionInfo: css2` display: flex; flex-direction: column; align-items: flex-start; gap: 0.25rem; flex: 1; `, noPluginsSuggestionPackage: css2` font-size: 0.95rem; font-weight: 600; color: ${t(colors.gray[900], colors.gray[100])}; margin: 0; font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace; `, noPluginsSuggestionSource: css2` font-size: 0.8rem; color: ${t(colors.gray[500], colors.gray[500])}; margin: 0; `, noPluginsSuggestionStatus: css2` display: flex; align-items: center; gap: 0.5rem; color: ${t(colors.green[600], colors.green[400])}; svg { width: 18px; height: 18px; } `, noPluginsSuggestionStatusText: css2` font-size: 0.875rem; font-weight: 500; `, noPluginsSuggestionStatusTextError: css2` font-size: 0.875rem; font-weight: 500; color: ${t(colors.red[600], colors.red[400])}; `, noPluginsEmptyState: css2` margin-top: 1.5rem; padding: 1.5rem; background: ${t(colors.white, colors.darkGray[800])}; border: 1px solid ${t(colors.gray[200], colors.gray[700])}; border-radius: 0.5rem; `, noPluginsEmptyStateText: css2` font-size: 0.875rem; color: ${t(colors.gray[600], colors.gray[400])}; margin: 0; line-height: 1.5; `, noPluginsFallbackLinks: css2` display: flex; align-items: center; gap: 0.75rem; margin-top: 1.5rem; `, noPluginsFallbackLink: css2` font-size: 0.875rem; color: ${t(colors.gray[700], colors.gray[300])}; text-decoration: none; transition: color 0.15s ease; &:hover { color: ${t(colors.gray[900], colors.gray[100])}; text-decoration: underline; } `, noPluginsFallbackLinkSeparator: css2` color: ${t(colors.gray[400], colors.gray[600])}; `, // Plugin Marketplace Styles (for "Add More" tab) pluginMarketplace: css2` width: 100%; overflow-y: auto; padding: 2rem; background: ${t( "linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%)", "linear-gradient(135deg, #1a1d23 0%, #13161a 100%)" )}; animation: ${fadeIn} 0.3s ease; `, pluginMarketplaceHeader: css2` margin-bottom: 2rem; padding-bottom: 1rem; border-bottom: 2px solid ${t(colors.gray[200], colors.gray[700])}; `, pluginMarketplaceTitleRow: css2` display: flex; align-items: center; justify-content: space-between; gap: 2rem; margin-bottom: 0.5rem; `, pluginMarketplaceTitle: css2` font-size: 1.5rem; font-weight: 700; color: ${t(colors.gray[900], colors.gray[100])}; margin: 0; letter-spacing: -0.02em; `, pluginMarketplaceDescription: css2` font-size: 0.95rem; color: ${t(colors.gray[600], colors.gray[400])}; margin: 0 0 1rem 0; line-height: 1.5; `, pluginMarketplaceSearchWrapper: css2` position: relative; display: flex; align-items: center; max-width: 400px; flex-shrink: 0; svg { position: absolute; left: 1rem; color: ${t(colors.gray[400], colors.gray[500])}; pointer-events: none; } `, pluginMarketplaceSearch: css2` width: 100%; padding: 0.75rem 1rem 0.75rem 2.75rem; background: ${t(colors.gray[50], colors.darkGray[900])}; border: 2px solid ${t(colors.gray[200], colors.gray[700])}; border-radius: 0.5rem; color: ${t(colors.gray[900], colors.gray[100])}; font-size: 0.875rem; font-family: ${fontFamily.sans}; transition: all 0.2s ease; &::placeholder { color: ${t(colors.gray[400], colors.gray[500])}; } &:focus { outline: none; border-color: ${t(colors.blue[500], colors.blue[400])}; background: ${t(colors.white, colors.darkGray[800])}; box-shadow: 0 0 0 3px ${t("rgba(59, 130, 246, 0.1)", "rgba(96, 165, 250, 0.1)")}; } `, pluginMarketplaceFilters: css2` margin-top: 1.5rem; padding-top: 1rem; `, pluginMarketplaceTagsContainer: css2` display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 1.5rem; padding: 1rem; background: ${t(colors.gray[50], colors.darkGray[800])}; border: 1px solid ${t(colors.gray[200], colors.gray[700])}; border-radius: 0.5rem; `, pluginMarketplaceTagButton: css2` padding: 0.5rem 1rem; font-size: 0.875rem; font-weight: 500; background: ${t(colors.white, colors.darkGray[700])}; border: 2px solid ${t(colors.gray[300], colors.gray[600])}; border-radius: 0.375rem; color: ${t(colors.gray[700], colors.gray[300])}; cursor: pointer; transition: all 0.15s ease; &:hover { background: ${t(colors.gray[100], colors.darkGray[600])}; border-color: ${t(colors.gray[400], colors.gray[500])}; color: ${t(colors.gray[900], colors.gray[100])}; } `, pluginMarketplaceTagButtonActive: css2` background: ${t( "linear-gradient(135deg, #3b82f6 0%, #2563eb 100%)", "linear-gradient(135deg, #60a5fa 0%, #3b82f6 100%)" )} !important; border-color: ${t("#2563eb", "#3b82f6")} !important; color: white !important; &:hover { background: ${t( "linear-gradient(135deg, #2563eb 0%, #1d4ed8 100%)", "linear-gradient(135deg, #3b82f6 0%, #2563eb 100%)" )} !important; border-color: ${t("#1d4ed8", "#2563eb")} !important; } `, pluginMarketplaceSettingsButton: css2` display: flex; align-items: center; justify-content: center; padding: 0.75rem; background: ${t(colors.gray[100], colors.darkGray[800])}; border: 2px solid ${t(colors.gray[200], colors.gray[700])}; border-radius: 0.5rem; color: ${t(colors.gray[700], colors.gray[300])}; cursor: pointer; transition: all 0.2s ease; margin-left: 0.5rem; &:hover { background: ${t(colors.gray[200], colors.darkGray[700])}; border-color: ${t(colors.gray[300], colors.gray[600])}; color: ${t(colors.gray[900], colors.gray[100])}; } &:active { transform: scale(0.95); } `, pluginMarketplaceSettingsPanel: css2` position: fixed; top: 0; right: 0; bottom: 0; width: 350px; background: ${t(colors.white, colors.darkGray[800])}; border-left: 1px solid ${t(colors.gray[200], colors.gray[700])}; box-shadow: -4px 0 12px ${t("rgba(0, 0, 0, 0.1)", "rgba(0, 0, 0, 0.4)")}; z-index: 1000; display: flex; flex-direction: column; animation: ${slideInRight} 0.3s ease; `, pluginMarketplaceSettingsPanelHeader: css2` display: flex; align-items: center; justify-content: space-between; padding: 1.5rem; border-bottom: 1px solid ${t(colors.gray[200], colors.gray[700])}; `, pluginMarketplaceSettingsPanelTitle: css2` font-size: 1.125rem; font-weight: 600; color: ${t(colors.gray[900], colors.gray[100])}; margin: 0; `, pluginMarketplaceSettingsPanelClose: css2` display: flex; align-items: center; justify-content: center; padding: 0.5rem; background: transparent; border: none; color: ${t(colors.gray[600], colors.gray[400])}; cursor: pointer; border-radius: 0.375rem; transition: all 0.15s ease; &:hover { background: ${t(colors.gray[100], colors.darkGray[700])}; color: ${t(colors.gray[900], colors.gray[100])}; } `, pluginMarketplaceSettingsPanelContent: css2` flex: 1; padding: 1.5rem; overflow-y: auto; `, pluginMarketplaceGrid: css2` display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 1.25rem; animation: ${slideUp} 0.4s ease; `, pluginMarketplaceCard: css2` background: ${t(colors.white, colors.darkGray[800])}; border: 2px solid ${t(colors.gray[200], colors.gray[700])}; border-radius: 0.75rem; padding: 1.5rem; display: flex; flex-direction: column; gap: 1rem; transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1); position: relative; overflow: hidden; &::before { content: ''; position: absolute; top: 0; left: 0; right: 0; height: 3px; background: ${t( "linear-gradient(90deg, #3b82f6 0%, #8b5cf6 100%)", "linear-gradient(90deg, #60a5fa 0%, #a78bfa 100%)" )}; transform: scaleX(0); transform-origin: left; transition: transform 0.25s ease; } &:hover { border-color: ${t(colors.gray[400], colors.gray[500])}; box-shadow: 0 8px 24px ${t("rgba(0,0,0,0.1)", "rgba(0,0,0,0.4)")}; transform: translateY(-4px); &::before { transform: scaleX(1); } } `, pluginMarketplaceCardIcon: css2` width: 40px; height: 40px; display: flex; align-items: center; justify-content: center; background: ${t( "linear-gradient(135deg, #3b82f6 0%, #8b5cf6 100%)", "linear-gradient(135deg, #60a5fa 0%, #a78bfa 100%)" )}; border-radius: 0.5rem; color: white; transition: transform 0.25s ease; svg { width: 20px; height: 20px; } &.custom-logo { } `, pluginMarketplaceCardHeader: css2` flex: 1; `, pluginMarketplaceCardTitle: css2` font-size: 0.95rem; font-weight: 600; color: ${t(colors.gray[900], colors.gray[100])}; margin: 0 0 0.5rem 0; line-height: 1.4; `, pluginMarketplaceCardDescription: css2` font-size: 0.8rem; color: ${t(colors.gray[500], colors.gray[500])}; margin: 0; padding: 0; background: transparent; border-radius: 0.375rem; display: block; font-weight: 500; `, pluginMarketplaceCardPackageBadge: css2` margin-top: 4px; margin-bottom: 8px; font-size: 0.6875rem; font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace; opacity: 0.6; padding: 4px 8px; padding-left: 0; background-color: var(--bg-tertiary); border-radius: 4px; word-break: break-all; display: inline-block; `, pluginMarketplaceCardDescriptionText: css2` line-height: 1.5; margin-top: 0; `, pluginMarketplaceCardVersionInfo: css2` margin-top: 8px; font-size: 0.6875rem; font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace; `, pluginMarketplaceCardVersionSatisfied: css2` color: ${t(colors.green[600], colors.green[400])}; `, pluginMarketplaceCardVersionUnsatisfied: css2` color: ${t(colors.red[600], colors.red[400])}; `, pluginMarketplaceCardDocsLink: css2` display: inline-flex; align-items: center; gap: 0.25rem; font-size: 0.75rem; color: ${t(colors.blue[600], colors.blue[400])}; text-decoration: none; margin-top: 0.5rem; transition: color 0.15s ease; &:hover { color: ${t(colors.blue[700], colors.blue[300])}; text-decoration: underline; } svg { width: 12px; height: 12px; } `, pluginMarketplaceCardTags: css2` display: flex; flex-wrap: wrap; gap: 0.375rem; margin-top: 0.75rem; `, pluginMarketplaceCardTag: css2` font-size: 0.6875rem; font-weight: 500; padding: 0.25rem 0.5rem; background: ${t(colors.gray[100], colors.darkGray[700])}; border: 1px solid ${t(colors.gray[300], colors.gray[600])}; border-radius: 0.25rem; color: ${t(colors.gray[700], colors.gray[300])}; `, pluginMarketplaceCardImage: css2` width: 28px; height: 28px; object-fit: contain; `, pluginMarketplaceNewBanner: css2` position: absolute; top: 12px; right: -35px; background-color: ${t(colors.green[500], colors.green[500])}; color: white; padding: 4px 40px; font-size: 0.6875rem; font-weight: bold; text-transform: uppercase; transform: rotate(45deg); box-shadow: 0 2px 8px rgba(16, 185, 129, 0.5); z-index: 10; letter-spacing: 0.5px; `, pluginMarketplaceCardFeatured: css2` border-color: ${t(colors.blue[500], colors.blue[400])}; border-width: 2px; `, pluginMarketplaceCardActive: css2` border-color: ${t(colors.green[500], colors.green[600])}; border-width: 2px; &:hover { border-color: ${t(colors.green[500], colors.green[600])}; box-shadow: none; transform: none; &::before { transform: scaleX(0); } } `, pluginMarketplaceCardStatus: css2` display: flex; align-items: center; gap: 0.5rem; color: ${t(colors.green[600], colors.green[400])}; animation: ${statusFadeIn} 0.3s ease; svg { width: 18px; height: 18px; animation: ${iconPop} 0.3s cubic-bezier(0.68, -0.55, 0.265, 1.55); } `, pluginMarketplaceCardSpinner: css2` width: 18px; height: 18px; border: 2px solid ${t(colors.gray[200], colors.gray[700])}; border-top-color: ${t(colors.blue[600], colors.blue[400])}; border-radius: 50%; animation: ${spin} 0.8s linear infinite; `, pluginMarketplaceCardStatusText: css2` font-size: 0.875rem; font-weight: 600; `, pluginMarketplaceCardStatusTextError: css2` font-size: 0.875rem; font-weight: 600; color: ${t(colors.red[600], colors.red[400])}; `, pluginMarketplaceEmpty: css2` padding: 3rem 2rem; text-align: center; background: ${t(colors.white, colors.darkGray[800])}; border: 2px dashed ${t(colors.gray[300], colors.gray[700])}; border-radiu