@dev_bachani/math-editor 0.0.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/README.md +199 -0
- package/dist/components/MathInput/MathInput.d.ts +51 -0
- package/dist/components/MathInput/MathInput.d.ts.map +1 -0
- package/dist/components/MathKeyboard/MathKeyboard.d.ts +25 -0
- package/dist/components/MathKeyboard/MathKeyboard.d.ts.map +1 -0
- package/dist/components/MathKeyboard/keyboardData.d.ts +46 -0
- package/dist/components/MathKeyboard/keyboardData.d.ts.map +1 -0
- package/dist/components/MathProvider/MathProvider.d.ts +56 -0
- package/dist/components/MathProvider/MathProvider.d.ts.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/mathex.cjs +2 -0
- package/dist/mathex.cjs.map +1 -0
- package/dist/mathex.css +1 -0
- package/dist/mathex.js +745 -0
- package/dist/mathex.js.map +1 -0
- package/dist/mathex.umd.js +2 -0
- package/dist/mathex.umd.js.map +1 -0
- package/dist/types/index.d.ts +116 -0
- package/dist/types/index.d.ts.map +1 -0
- package/package.json +75 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mathex.cjs","sources":["../src/components/MathProvider/MathProvider.tsx","../src/components/MathInput/MathInput.tsx","../src/components/MathKeyboard/keyboardData.ts","../src/components/MathKeyboard/MathKeyboard.tsx"],"sourcesContent":["import React, { createContext, useContext, useState, useCallback, useRef, type ReactNode } from 'react';\r\nimport type { ThemeConfig } from '../../types';\r\n\r\n// Debug logging helper\r\nconst DEBUG = false;\r\nconst log = (component: string, action: string, data?: any) => {\r\n if (DEBUG) {\r\n console.log(`[${component}] ${action}`, data !== undefined ? data : '');\r\n }\r\n};\r\n\r\n/**\r\n * Props for the MathProvider component\r\n */\r\nexport interface MathProviderProps {\r\n /** Child components */\r\n children: ReactNode;\r\n /** Theme configuration (light, dark, or custom) */\r\n theme?: 'light' | 'dark' | ThemeConfig;\r\n /** Global configuration options */\r\n config?: {\r\n /** Default keyboard mode */\r\n defaultKeyboardMode?: 'basic' | 'calculus' | 'abc';\r\n /** KaTeX rendering options */\r\n katexOptions?: any;\r\n };\r\n}\r\n\r\n/**\r\n * Input registration callback type\r\n */\r\nexport type InputUpdateCallback = (latex: string) => void;\r\n\r\n/**\r\n * Context value shape\r\n */\r\ninterface MathContextValue {\r\n activeInputId: string | null;\r\n setActiveInput: (id: string) => void;\r\n insertAtCursor: (latex: string) => void;\r\n registerInput: (id: string, updateCallback: InputUpdateCallback) => void;\r\n unregisterInput: (id: string) => void;\r\n theme: 'light' | 'dark' | ThemeConfig;\r\n}\r\n\r\n/**\r\n * Context for sharing state between MathInput and MathKeyboard\r\n */\r\nconst MathContext = createContext<MathContextValue | undefined>(undefined);\r\n\r\n/**\r\n * Hook to access the math context\r\n * Optional - returns undefined if not within a provider\r\n */\r\nexport const useMathContext = () => {\r\n return useContext(MathContext);\r\n};\r\n\r\n/**\r\n * MathProvider - Context provider for Mathex components\r\n *\r\n * Manages global state and communication between MathInput and MathKeyboard.\r\n * Components will work automatically even without explicit MathProvider wrapping.\r\n *\r\n * @component\r\n * @example\r\n * ```tsx\r\n * <MathProvider theme=\"light\">\r\n * <MathInput />\r\n * <MathKeyboard />\r\n * </MathProvider>\r\n * ```\r\n */\r\nexport const MathProvider: React.FC<MathProviderProps> = ({\r\n children,\r\n theme = 'light',\r\n}) => {\r\n // State for tracking active input\r\n const [activeInputId, setActiveInputId] = useState<string | null>(null);\r\n\r\n // Ref to access activeInputId in callbacks without causing re-renders\r\n const activeInputIdRef = useRef<string | null>(null);\r\n activeInputIdRef.current = activeInputId;\r\n\r\n // Registry of input update callbacks\r\n const inputCallbacksRef = useRef<Map<string, InputUpdateCallback>>(new Map());\r\n\r\n /**\r\n * Register an input with its update callback\r\n */\r\n const registerInput = useCallback((id: string, updateCallback: InputUpdateCallback) => {\r\n log('MathProvider', 'registerInput', { id, totalRegistered: inputCallbacksRef.current.size + 1 });\r\n inputCallbacksRef.current.set(id, updateCallback);\r\n }, []);\r\n\r\n /**\r\n * Unregister an input\r\n */\r\n const unregisterInput = useCallback((id: string) => {\r\n log('MathProvider', 'unregisterInput', { id, totalRemaining: inputCallbacksRef.current.size - 1 });\r\n inputCallbacksRef.current.delete(id);\r\n setActiveInputId((current) => (current === id ? null : current));\r\n }, []);\r\n\r\n /**\r\n * Set the active input (called when an input receives focus)\r\n * NOTE: No dependencies needed - we just call the setter\r\n */\r\n const setActiveInput = useCallback((id: string) => {\r\n log('MathProvider', 'setActiveInput', { id });\r\n setActiveInputId(id);\r\n }, []);\r\n\r\n /**\r\n * Insert LaTeX at the cursor position of the active input\r\n * NOTE: Uses ref to access activeInputId to avoid dependency that causes context churn\r\n */\r\n const insertAtCursor = useCallback(\r\n (latex: string) => {\r\n const currentActiveId = activeInputIdRef.current;\r\n log('MathProvider', 'insertAtCursor called', {\r\n latex,\r\n activeInputId: currentActiveId,\r\n hasCallback: currentActiveId ? inputCallbacksRef.current.has(currentActiveId) : false,\r\n registeredInputs: Array.from(inputCallbacksRef.current.keys())\r\n });\r\n\r\n if (!currentActiveId) {\r\n log('MathProvider', 'WARNING: No active input to insert LaTeX into');\r\n console.warn('No active input to insert LaTeX into');\r\n return;\r\n }\r\n\r\n const updateCallback = inputCallbacksRef.current.get(currentActiveId);\r\n if (updateCallback) {\r\n log('MathProvider', 'Calling update callback for active input', { activeInputId: currentActiveId, latex });\r\n // Pass the command/latex to the input handler\r\n updateCallback(latex);\r\n } else {\r\n log('MathProvider', 'ERROR: No callback found for activeInputId', { activeInputId: currentActiveId });\r\n }\r\n },\r\n [] // Empty deps - uses refs to access current values\r\n );\r\n\r\n const contextValue: MathContextValue = {\r\n activeInputId,\r\n setActiveInput,\r\n insertAtCursor,\r\n registerInput,\r\n unregisterInput,\r\n theme,\r\n };\r\n\r\n // Determine theme attribute value (support both string and custom ThemeConfig)\r\n const themeAttr = typeof theme === 'string' ? theme : 'custom';\r\n\r\n log('MathProvider', 'rendering with contextValue', { activeInputId, registeredInputs: Array.from(inputCallbacksRef.current.keys()) });\r\n\r\n return (\r\n <MathContext.Provider value={contextValue}>\r\n <div data-theme={themeAttr} className=\"mathex-provider\">\r\n {children}\r\n </div>\r\n </MathContext.Provider>\r\n );\r\n};\r\n\r\nMathProvider.displayName = 'MathProvider';\r\n","import React, { useState, useRef, useEffect, useCallback, useMemo } from 'react';\r\nimport { useMathContext } from '../MathProvider/MathProvider';\r\nimport './MathInput.css';\r\n\r\n// Debug logging helper\r\nconst DEBUG = false;\r\nconst log = (component: string, action: string, data?: any) => {\r\n if (DEBUG) {\r\n console.log(`[${component}] ${action}`, data !== undefined ? data : '');\r\n }\r\n};\r\n\r\n// Use global MathQuill (loaded via CDN or script tag)\r\ndeclare global {\r\n interface Window {\r\n MathQuill: any;\r\n }\r\n}\r\n\r\n// Helper to get MathQuill API\r\nconst getMQ = () => {\r\n if (typeof window !== 'undefined' && window.MathQuill) {\r\n return window.MathQuill.getInterface(2);\r\n }\r\n return null;\r\n};\r\n\r\n/**\r\n * Props for the MathInput component\r\n */\r\nexport interface MathInputProps {\r\n /** Controlled LaTeX value */\r\n value?: string;\r\n /** Default LaTeX value (uncontrolled) */\r\n defaultValue?: string;\r\n /** Callback fired when the LaTeX changes */\r\n onChange?: (latex: string) => void;\r\n /** Unique identifier for this input */\r\n id?: string;\r\n /** Placeholder text when input is empty */\r\n placeholder?: string;\r\n /** Whether the input is disabled */\r\n disabled?: boolean;\r\n /** Additional CSS class name */\r\n className?: string;\r\n /** Inline styles */\r\n style?: React.CSSProperties;\r\n /** Whether to focus on mount */\r\n autoFocus?: boolean;\r\n /** Whether the input is read-only */\r\n readOnly?: boolean;\r\n /** Callback fired on errors */\r\n onError?: (error: Error) => void;\r\n}\r\n\r\n/**\r\n * MathInput - A WYSIWYG math equation editor using MathQuill\r\n *\r\n * This component provides a Desmos-like editing experience where you edit\r\n * rendered mathematical notation directly, not raw LaTeX.\r\n *\r\n * @component\r\n * @example\r\n * ```tsx\r\n * <MathInput\r\n * value={latex}\r\n * onChange={(newLatex) => setLatex(newLatex)}\r\n * placeholder=\"Enter equation...\"\r\n * />\r\n * ```\r\n */\r\nexport const MathInput: React.FC<MathInputProps> = ({\r\n value: controlledValue,\r\n defaultValue = '',\r\n onChange,\r\n id,\r\n placeholder = 'Enter equation...',\r\n disabled = false,\r\n className = '',\r\n style,\r\n autoFocus = false,\r\n readOnly = false,\r\n onError,\r\n}) => {\r\n // Determine if component is controlled or uncontrolled\r\n const isControlled = controlledValue !== undefined;\r\n const [uncontrolledValue, setUncontrolledValue] = useState(defaultValue);\r\n const latex = isControlled ? controlledValue : uncontrolledValue;\r\n\r\n // State\r\n const [isFocused, setIsFocused] = useState(false);\r\n\r\n // Refs\r\n const mathFieldRef = useRef<any>(null); // MathQuill MathField instance\r\n const containerRef = useRef<HTMLDivElement>(null);\r\n\r\n // Generate unique ID if not provided\r\n const inputId = useMemo(() => id || `math-input-${Math.random().toString(36).substr(2, 9)}`, [id]);\r\n\r\n // Get context (optional - component works without provider)\r\n const mathContext = useMathContext();\r\n\r\n // Store context and inputId in refs for use in event handlers (avoids stale closure)\r\n const mathContextRef = useRef(mathContext);\r\n const inputIdRef = useRef(inputId);\r\n useEffect(() => {\r\n mathContextRef.current = mathContext;\r\n inputIdRef.current = inputId;\r\n }, [mathContext, inputId]);\r\n\r\n log('MathInput', 'render', { inputId, hasContext: !!mathContext, activeInputId: mathContext?.activeInputId });\r\n\r\n /**\r\n * Initialize MathQuill on mount\r\n */\r\n useEffect(() => {\r\n if (!containerRef.current || mathFieldRef.current) return;\r\n\r\n const MQ = getMQ();\r\n if (!MQ) {\r\n console.error('MathQuill is not loaded. Make sure to include MathQuill script in your HTML.');\r\n return;\r\n }\r\n\r\n try {\r\n const config = {\r\n spaceBehavesLikeTab: true,\r\n leftRightIntoCmdGoes: 'up' as const,\r\n restrictMismatchedBrackets: true,\r\n autoCommands: 'pi theta sqrt sum prod int',\r\n autoOperatorNames: 'sin cos tan sec csc cot sinh cosh tanh log ln',\r\n handlers: {\r\n edit: (mathField: any) => {\r\n const newLatex = mathField.latex();\r\n if (isControlled) {\r\n onChange?.(newLatex);\r\n } else {\r\n setUncontrolledValue(newLatex);\r\n onChange?.(newLatex);\r\n }\r\n },\r\n enter: () => {\r\n // Blur on Enter key\r\n mathFieldRef.current?.blur();\r\n },\r\n },\r\n };\r\n\r\n const mathField = MQ.MathField(containerRef.current, config);\r\n mathFieldRef.current = mathField;\r\n\r\n // Set initial value\r\n mathField.latex(latex);\r\n\r\n // Handle focus/blur - CRITICAL: This is where we set the active input in context\r\n const element = containerRef.current;\r\n const handleFocusIn = () => {\r\n const currentInputId = inputIdRef.current;\r\n const currentContext = mathContextRef.current;\r\n log('MathInput', 'focusin event fired', { inputId: currentInputId, hasContext: !!currentContext });\r\n setIsFocused(true);\r\n // Set this input as active in the context when it receives focus\r\n if (currentContext) {\r\n log('MathInput', 'Setting active input from focusin', { inputId: currentInputId });\r\n currentContext.setActiveInput(currentInputId);\r\n } else {\r\n log('MathInput', 'WARNING: No mathContext available in focusin handler');\r\n }\r\n };\r\n const handleFocusOut = () => {\r\n log('MathInput', 'focusout event fired', { inputId: inputIdRef.current });\r\n setIsFocused(false);\r\n };\r\n\r\n element.addEventListener('focusin', handleFocusIn);\r\n element.addEventListener('focusout', handleFocusOut);\r\n\r\n // Auto-focus if requested\r\n if (autoFocus) {\r\n mathField.focus();\r\n }\r\n\r\n return () => {\r\n log('MathInput', 'cleanup - removing listeners', { inputId });\r\n element.removeEventListener('focusin', handleFocusIn);\r\n element.removeEventListener('focusout', handleFocusOut);\r\n mathField.revert();\r\n mathFieldRef.current = null;\r\n };\r\n } catch (error) {\r\n if (onError && error instanceof Error) {\r\n onError(error);\r\n }\r\n console.error('Failed to initialize MathQuill:', error);\r\n }\r\n }, []);\r\n\r\n /**\r\n * Update MathQuill when controlled value changes externally\r\n */\r\n useEffect(() => {\r\n if (mathFieldRef.current && isControlled) {\r\n const currentLatex = mathFieldRef.current.latex();\r\n if (currentLatex !== controlledValue) {\r\n mathFieldRef.current.latex(controlledValue);\r\n }\r\n }\r\n }, [controlledValue, isControlled]);\r\n\r\n /**\r\n * Handle focus\r\n */\r\n const handleFocus = useCallback(() => {\r\n if (mathFieldRef.current && !disabled && !readOnly) {\r\n mathFieldRef.current.focus();\r\n // Notify provider that this input is now active\r\n if (mathContext) {\r\n mathContext.setActiveInput(inputId);\r\n }\r\n }\r\n }, [mathContext, inputId, disabled, readOnly]);\r\n\r\n /**\r\n * Handle keyboard insertions from MathKeyboard\r\n */\r\n const handleKeyboardInsertion = useCallback(\r\n (insertedLatex: string) => {\r\n log('MathInput', 'handleKeyboardInsertion called', {\r\n insertedLatex,\r\n hasMathField: !!mathFieldRef.current,\r\n inputId: inputIdRef.current\r\n });\r\n\r\n if (!mathFieldRef.current) {\r\n log('MathInput', 'ERROR: mathFieldRef.current is null, cannot insert');\r\n return;\r\n }\r\n\r\n // Handle special commands\r\n switch (insertedLatex) {\r\n case 'BACKSPACE':\r\n log('MathInput', 'Executing backspace keystroke');\r\n mathFieldRef.current.keystroke('Backspace');\r\n return;\r\n case 'ARROW_LEFT':\r\n log('MathInput', 'Executing Left arrow keystroke');\r\n mathFieldRef.current.keystroke('Left');\r\n return;\r\n case 'ARROW_RIGHT':\r\n log('MathInput', 'Executing Right arrow keystroke');\r\n mathFieldRef.current.keystroke('Right');\r\n return;\r\n case 'ENTER':\r\n log('MathInput', 'Executing blur (Enter)');\r\n mathFieldRef.current.blur();\r\n return;\r\n default:\r\n // Insert LaTeX at cursor\r\n log('MathInput', 'Writing LaTeX to MathQuill', { latex: insertedLatex });\r\n mathFieldRef.current.write(insertedLatex);\r\n // Re-focus after insertion to ensure subsequent inputs work\r\n log('MathInput', 'Re-focusing MathQuill after write');\r\n mathFieldRef.current.focus();\r\n }\r\n },\r\n []\r\n );\r\n\r\n /**\r\n * Register with provider on mount, unregister on unmount\r\n * CRITICAL: Uses refs to avoid re-running when context object reference changes\r\n * This prevents the register/unregister cascade that was resetting activeInputId\r\n */\r\n useEffect(() => {\r\n const currentContext = mathContextRef.current;\r\n const currentInputId = inputIdRef.current;\r\n\r\n if (currentContext) {\r\n log('MathInput', 'Registering input with provider (mount)', { inputId: currentInputId });\r\n currentContext.registerInput(currentInputId, handleKeyboardInsertion);\r\n return () => {\r\n log('MathInput', 'Unregistering input from provider (unmount)', { inputId: currentInputId });\r\n currentContext.unregisterInput(currentInputId);\r\n };\r\n } else {\r\n log('MathInput', 'WARNING: No mathContext available for registration', { inputId: currentInputId });\r\n }\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, []); // Run only on mount - uses refs to access current values\r\n\r\n /**\r\n * Update disabled/readonly state\r\n */\r\n useEffect(() => {\r\n if (mathFieldRef.current && containerRef.current) {\r\n if (disabled || readOnly) {\r\n containerRef.current.setAttribute('contenteditable', 'false');\r\n containerRef.current.style.pointerEvents = 'none';\r\n containerRef.current.style.opacity = '0.6';\r\n } else {\r\n containerRef.current.removeAttribute('contenteditable');\r\n containerRef.current.style.pointerEvents = '';\r\n containerRef.current.style.opacity = '';\r\n }\r\n }\r\n }, [disabled, readOnly]);\r\n\r\n return (\r\n <div\r\n className={`mathex-input mathex-input--mathquill ${isFocused ? 'mathex-input--focused' : ''} ${\r\n disabled ? 'mathex-input--disabled' : ''\r\n } ${className}`}\r\n style={style}\r\n onClick={handleFocus}\r\n data-id={id}\r\n >\r\n <div\r\n ref={containerRef}\r\n className=\"mathex-mathquill-container\"\r\n data-placeholder={!latex ? placeholder : undefined}\r\n />\r\n </div>\r\n );\r\n};\r\n\r\nMathInput.displayName = 'MathInput';\r\n","/**\r\n * Keyboard layout data and configurations for MathKeyboard\r\n * Based on Desmos calculator keyboard\r\n */\r\n\r\nimport type { ButtonConfig, FunctionCategory } from '../../types';\r\n\r\n// ============================================\r\n// DEFAULT KEYBOARD LAYOUT (Numbers + Variables)\r\n// ============================================\r\n\r\n/**\r\n * Left section: Variables, parentheses, etc.\r\n * Layout:\r\n * [x] [y] [a²] [aᵇ]\r\n * [(] [)] [<] [>]\r\n * [|a|][,] [≤] [≥]\r\n * [ABC][🔊][√] [π]\r\n */\r\nexport const defaultLeftSection: ButtonConfig[][] = [\r\n [\r\n { display: 'x', latex: 'x', type: 'variable', style: 'white' },\r\n { display: 'y', latex: 'y', type: 'variable', style: 'white' },\r\n { display: 'a²', latex: '^{2}', type: 'operator', style: 'white' },\r\n { display: 'aᵇ', latex: '^{}', type: 'operator', style: 'white' },\r\n ],\r\n [\r\n { display: '(', latex: '(', type: 'symbol', style: 'white' },\r\n { display: ')', latex: ')', type: 'symbol', style: 'white' },\r\n { display: '<', latex: '<', type: 'operator', style: 'white' },\r\n { display: '>', latex: '>', type: 'operator', style: 'white' },\r\n ],\r\n [\r\n { display: '|a|', latex: '||', type: 'operator', style: 'white' },\r\n { display: ',', latex: ',', type: 'symbol', style: 'white' },\r\n { display: '≤', latex: '\\\\leq ', type: 'operator', style: 'white' },\r\n { display: '≥', latex: '\\\\geq ', type: 'operator', style: 'white' },\r\n ],\r\n [\r\n { display: 'A B C', latex: 'ABC_MODE', type: 'action', style: 'gray-light' },\r\n { display: '🔊', latex: 'SPEAK', type: 'action', style: 'gray-light' },\r\n { display: '√', latex: '\\\\sqrt{}', type: 'function', style: 'white' },\r\n { display: 'π', latex: '\\\\pi ', type: 'symbol', style: 'white' },\r\n ],\r\n];\r\n\r\n/**\r\n * Middle section: Number pad + operators\r\n * Layout:\r\n * [7][8][9][÷]\r\n * [4][5][6][×]\r\n * [1][2][3][−]\r\n * [0][.][=][+]\r\n */\r\nexport const defaultMiddleSection: ButtonConfig[][] = [\r\n [\r\n { display: '7', latex: '7', type: 'number', style: 'gray-light' },\r\n { display: '8', latex: '8', type: 'number', style: 'gray-light' },\r\n { display: '9', latex: '9', type: 'number', style: 'gray-light' },\r\n { display: '÷', latex: '\\\\div ', type: 'operator', style: 'white' },\r\n ],\r\n [\r\n { display: '4', latex: '4', type: 'number', style: 'gray-light' },\r\n { display: '5', latex: '5', type: 'number', style: 'gray-light' },\r\n { display: '6', latex: '6', type: 'number', style: 'gray-light' },\r\n { display: '×', latex: '\\\\times ', type: 'operator', style: 'white' },\r\n ],\r\n [\r\n { display: '1', latex: '1', type: 'number', style: 'gray-light' },\r\n { display: '2', latex: '2', type: 'number', style: 'gray-light' },\r\n { display: '3', latex: '3', type: 'number', style: 'gray-light' },\r\n { display: '−', latex: '-', type: 'operator', style: 'white' },\r\n ],\r\n [\r\n { display: '0', latex: '0', type: 'number', style: 'gray-light' },\r\n { display: '.', latex: '.', type: 'number', style: 'gray-light' },\r\n { display: '=', latex: '=', type: 'operator', style: 'gray-light' },\r\n { display: '+', latex: '+', type: 'operator', style: 'white' },\r\n ],\r\n];\r\n\r\n/**\r\n * Right section: Functions, navigation, actions\r\n * Layout:\r\n * [ functions ]\r\n * [ ← ][ → ]\r\n * [ backspace ]\r\n * [ enter ]\r\n */\r\nexport const defaultRightSection: ButtonConfig[][] = [\r\n [\r\n { display: 'functions', latex: 'FUNCTIONS', type: 'action', style: 'gray-light', size: 'extra-wide' },\r\n ],\r\n [\r\n { display: '←', latex: 'ARROW_LEFT', type: 'action', style: 'gray-light' },\r\n { display: '→', latex: 'ARROW_RIGHT', type: 'action', style: 'gray-light' },\r\n ],\r\n [\r\n { display: '⌫', latex: 'BACKSPACE', type: 'action', style: 'gray-light', size: 'extra-wide' },\r\n ],\r\n [\r\n { display: '↵', latex: 'ENTER', type: 'action', style: 'blue', size: 'extra-wide' },\r\n ],\r\n];\r\n\r\n// ============================================\r\n// ABC KEYBOARD LAYOUT (Letters)\r\n// ============================================\r\n\r\n/**\r\n * ABC keyboard - QWERTY layout\r\n * Row 1: q w e r t y u i o p\r\n * Row 2: a s d f g h j k l θ\r\n * Row 3: ⬆ z x c v b n m ⌫\r\n * Row 4: 123 aᵦ !% [] {} ~ ,' ↵\r\n */\r\nexport const abcKeyboardRows: ButtonConfig[][] = [\r\n // Row 1\r\n [\r\n { display: 'q', latex: 'q', type: 'letter', style: 'white' },\r\n { display: 'w', latex: 'w', type: 'letter', style: 'white' },\r\n { display: 'e', latex: 'e', type: 'letter', style: 'white' },\r\n { display: 'r', latex: 'r', type: 'letter', style: 'white' },\r\n { display: 't', latex: 't', type: 'letter', style: 'white' },\r\n { display: 'y', latex: 'y', type: 'letter', style: 'white' },\r\n { display: 'u', latex: 'u', type: 'letter', style: 'white' },\r\n { display: 'i', latex: 'i', type: 'letter', style: 'white' },\r\n { display: 'o', latex: 'o', type: 'letter', style: 'white' },\r\n { display: 'p', latex: 'p', type: 'letter', style: 'white' },\r\n ],\r\n // Row 2\r\n [\r\n { display: 'a', latex: 'a', type: 'letter', style: 'white' },\r\n { display: 's', latex: 's', type: 'letter', style: 'white' },\r\n { display: 'd', latex: 'd', type: 'letter', style: 'white' },\r\n { display: 'f', latex: 'f', type: 'letter', style: 'white' },\r\n { display: 'g', latex: 'g', type: 'letter', style: 'white' },\r\n { display: 'h', latex: 'h', type: 'letter', style: 'white' },\r\n { display: 'j', latex: 'j', type: 'letter', style: 'white' },\r\n { display: 'k', latex: 'k', type: 'letter', style: 'white' },\r\n { display: 'l', latex: 'l', type: 'letter', style: 'white' },\r\n { display: 'θ', latex: '\\\\theta ', type: 'symbol', style: 'white' },\r\n ],\r\n // Row 3\r\n [\r\n { display: '⬆', latex: 'SHIFT', type: 'action', style: 'gray-light', size: 'wide' },\r\n { display: 'z', latex: 'z', type: 'letter', style: 'white' },\r\n { display: 'x', latex: 'x', type: 'letter', style: 'white' },\r\n { display: 'c', latex: 'c', type: 'letter', style: 'white' },\r\n { display: 'v', latex: 'v', type: 'letter', style: 'white' },\r\n { display: 'b', latex: 'b', type: 'letter', style: 'white' },\r\n { display: 'n', latex: 'n', type: 'letter', style: 'white' },\r\n { display: 'm', latex: 'm', type: 'letter', style: 'white' },\r\n { display: '⌫', latex: 'BACKSPACE', type: 'action', style: 'gray-light', size: 'wide' },\r\n ],\r\n // Row 4\r\n [\r\n { display: '1 2 3', latex: '123_MODE', type: 'action', style: 'gray-light', size: 'wide' },\r\n { display: 'aᵦ', latex: 'SUBSCRIPT', type: 'action', style: 'white' },\r\n {\r\n display: '! %',\r\n latex: 'DUAL_EXCLAIM_PERCENT',\r\n type: 'symbol',\r\n style: 'white',\r\n dualChar: {\r\n primary: '!',\r\n primaryLatex: '!',\r\n secondary: '%',\r\n secondaryLatex: '%',\r\n }\r\n },\r\n {\r\n display: '[ ]',\r\n latex: 'DUAL_BRACKETS',\r\n type: 'symbol',\r\n style: 'white',\r\n dualChar: {\r\n primary: '[',\r\n primaryLatex: '[',\r\n secondary: ']',\r\n secondaryLatex: ']',\r\n }\r\n },\r\n {\r\n display: '{ }',\r\n latex: 'DUAL_BRACES',\r\n type: 'symbol',\r\n style: 'white',\r\n dualChar: {\r\n primary: '{',\r\n primaryLatex: '\\\\{',\r\n secondary: '}',\r\n secondaryLatex: '\\\\}',\r\n }\r\n },\r\n {\r\n display: '~ :',\r\n latex: 'DUAL_TILDE_COLON',\r\n type: 'symbol',\r\n style: 'white',\r\n dualChar: {\r\n primary: '~',\r\n primaryLatex: '\\\\sim ',\r\n secondary: ':',\r\n secondaryLatex: ':',\r\n }\r\n },\r\n {\r\n display: \", '\",\r\n latex: 'DUAL_COMMA_QUOTE',\r\n type: 'symbol',\r\n style: 'white',\r\n dualChar: {\r\n primary: ',',\r\n primaryLatex: ',',\r\n secondary: \"'\",\r\n secondaryLatex: \"'\",\r\n }\r\n },\r\n { display: '↵', latex: 'ENTER', type: 'action', style: 'blue', size: 'wide' },\r\n ],\r\n];\r\n\r\n// ============================================\r\n// FUNCTIONS PANEL - All 13 Categories\r\n// ============================================\r\n\r\nexport const functionCategories: FunctionCategory[] = [\r\n // 1. TRIG FUNCTIONS\r\n {\r\n id: 'trig',\r\n name: 'TRIG FUNCTIONS',\r\n functions: [\r\n { display: 'sin', latex: '\\\\sin(', description: 'Sine function' },\r\n { display: 'cos', latex: '\\\\cos(', description: 'Cosine function' },\r\n { display: 'tan', latex: '\\\\tan(', description: 'Tangent function' },\r\n { display: 'csc', latex: '\\\\csc(', description: 'Cosecant function' },\r\n { display: 'sec', latex: '\\\\sec(', description: 'Secant function' },\r\n { display: 'cot', latex: '\\\\cot(', description: 'Cotangent function' },\r\n ],\r\n },\r\n // 2. INVERSE TRIG FUNCTIONS\r\n {\r\n id: 'inverse-trig',\r\n name: 'INVERSE TRIG FUNCTIONS',\r\n functions: [\r\n { display: 'sin⁻¹', latex: '\\\\sin^{-1}(', description: 'Inverse sine' },\r\n { display: 'cos⁻¹', latex: '\\\\cos^{-1}(', description: 'Inverse cosine' },\r\n { display: 'tan⁻¹', latex: '\\\\tan^{-1}(', description: 'Inverse tangent' },\r\n { display: 'csc⁻¹', latex: '\\\\csc^{-1}(', description: 'Inverse cosecant' },\r\n { display: 'sec⁻¹', latex: '\\\\sec^{-1}(', description: 'Inverse secant' },\r\n { display: 'cot⁻¹', latex: '\\\\cot^{-1}(', description: 'Inverse cotangent' },\r\n ],\r\n },\r\n // 3. STATISTICS\r\n {\r\n id: 'statistics',\r\n name: 'STATISTICS',\r\n functions: [\r\n { display: 'mean', latex: '\\\\text{mean}(', description: 'Mean/average' },\r\n { display: 'median', latex: '\\\\text{median}(', description: 'Median value' },\r\n { display: 'min', latex: '\\\\min(', description: 'Minimum value' },\r\n { display: 'max', latex: '\\\\max(', description: 'Maximum value' },\r\n { display: 'quartile', latex: '\\\\text{quartile}(', description: 'Quartile' },\r\n { display: 'quantile', latex: '\\\\text{quantile}(', description: 'Quantile' },\r\n { display: 'stdev', latex: '\\\\text{stdev}(', description: 'Standard deviation' },\r\n { display: 'stdevp', latex: '\\\\text{stdevp}(', description: 'Population std dev' },\r\n { display: 'var', latex: '\\\\text{var}(', description: 'Variance' },\r\n { display: 'varp', latex: '\\\\text{varp}(', description: 'Population variance' },\r\n { display: 'cov', latex: '\\\\text{cov}(', description: 'Covariance' },\r\n { display: 'covp', latex: '\\\\text{covp}(', description: 'Population covariance' },\r\n { display: 'mad', latex: '\\\\text{mad}(', description: 'Mean absolute deviation' },\r\n { display: 'corr', latex: '\\\\text{corr}(', description: 'Correlation' },\r\n { display: 'spearman', latex: '\\\\text{spearman}(', description: 'Spearman correlation' },\r\n { display: 'stats', latex: '\\\\text{stats}(', description: 'Statistics summary' },\r\n { display: 'count', latex: '\\\\text{count}(', description: 'Count' },\r\n { display: 'total', latex: '\\\\text{total}(', description: 'Total/sum' },\r\n ],\r\n },\r\n // 4. LIST OPERATIONS\r\n {\r\n id: 'list-operations',\r\n name: 'LIST OPERATIONS',\r\n functions: [\r\n { display: 'repeat', latex: '\\\\text{repeat}(', description: 'Repeat elements' },\r\n { display: 'join', latex: '\\\\text{join}(', description: 'Join lists' },\r\n { display: 'sort', latex: '\\\\text{sort}(', description: 'Sort list' },\r\n { display: 'shuffle', latex: '\\\\text{shuffle}(', description: 'Shuffle list' },\r\n { display: 'unique', latex: '\\\\text{unique}(', description: 'Unique elements' },\r\n { display: 'for', latex: '\\\\text{for}', description: 'For loop' },\r\n ],\r\n },\r\n // 5. VISUALIZATIONS\r\n {\r\n id: 'visualizations',\r\n name: 'VISUALIZATIONS',\r\n functions: [\r\n { display: 'histogram', latex: '\\\\text{histogram}(', description: 'Histogram' },\r\n { display: 'dotplot', latex: '\\\\text{dotplot}(', description: 'Dot plot' },\r\n { display: 'boxplot', latex: '\\\\text{boxplot}(', description: 'Box plot' },\r\n ],\r\n },\r\n // 6. PROBABILITY DISTRIBUTIONS\r\n {\r\n id: 'distributions',\r\n name: 'PROBABILITY DISTRIBUTIONS',\r\n functions: [\r\n { display: 'normaldist', latex: '\\\\text{normaldist}(', description: 'Normal distribution' },\r\n { display: 'tdist', latex: '\\\\text{tdist}(', description: 'T distribution' },\r\n { display: 'chisqdist', latex: '\\\\text{chisqdist}(', description: 'Chi-squared distribution' },\r\n { display: 'uniformdist', latex: '\\\\text{uniformdist}(', description: 'Uniform distribution' },\r\n { display: 'binomialdist', latex: '\\\\text{binomialdist}(', description: 'Binomial distribution' },\r\n { display: 'poissondist', latex: '\\\\text{poissondist}(', description: 'Poisson distribution' },\r\n { display: 'geodist', latex: '\\\\text{geodist}(', description: 'Geometric distribution' },\r\n { display: 'pdf', latex: '\\\\text{pdf}(', description: 'Probability density function' },\r\n { display: 'cdf', latex: '\\\\text{cdf}(', description: 'Cumulative distribution function' },\r\n { display: 'inversecdf', latex: '\\\\text{inversecdf}(', description: 'Inverse CDF' },\r\n { display: 'random', latex: '\\\\text{random}(', description: 'Random number' },\r\n ],\r\n },\r\n // 7. INFERENCE\r\n {\r\n id: 'inference',\r\n name: 'INFERENCE',\r\n functions: [\r\n { display: 'ztest', latex: '\\\\text{ztest}(', description: 'Z-test' },\r\n { display: 'ttest', latex: '\\\\text{ttest}(', description: 'T-test' },\r\n { display: 'zproptest', latex: '\\\\text{zproptest}(', description: 'Z proportion test' },\r\n { display: 'chisqtest', latex: '\\\\text{chisqtest}(', description: 'Chi-squared test' },\r\n { display: 'chisqgof', latex: '\\\\text{chisqgof}(', description: 'Chi-squared goodness of fit' },\r\n { display: 'null', latex: '\\\\text{null}(', description: 'Null hypothesis' },\r\n { display: 'p', latex: '\\\\text{p}(', description: 'P-value' },\r\n { display: 'pleft', latex: '\\\\text{pleft}(', description: 'Left p-value' },\r\n { display: 'pright', latex: '\\\\text{pright}(', description: 'Right p-value' },\r\n { display: 'score', latex: '\\\\text{score}(', description: 'Test score' },\r\n { display: 'dof', latex: '\\\\text{dof}(', description: 'Degrees of freedom' },\r\n { display: 'stderr', latex: '\\\\text{stderr}(', description: 'Standard error' },\r\n { display: 'conf', latex: '\\\\text{conf}(', description: 'Confidence interval' },\r\n { display: 'lower', latex: '\\\\text{lower}(', description: 'Lower bound' },\r\n { display: 'upper', latex: '\\\\text{upper}(', description: 'Upper bound' },\r\n { display: 'estimate', latex: '\\\\text{estimate}(', description: 'Point estimate' },\r\n ],\r\n },\r\n // 8. CALCULUS\r\n {\r\n id: 'calculus',\r\n name: 'CALCULUS',\r\n functions: [\r\n { display: 'exp', latex: 'e^{', description: 'Exponential' },\r\n { display: 'ln', latex: '\\\\ln(', description: 'Natural logarithm' },\r\n { display: 'log', latex: '\\\\log(', description: 'Logarithm base 10' },\r\n { display: 'logₐ', latex: '\\\\log_{}(', description: 'Logarithm base a' },\r\n { display: 'd/dx', latex: '\\\\frac{d}{dx}', description: 'Derivative' },\r\n { display: \"f'\", latex: \"'\", description: 'Prime notation' },\r\n { display: '∫', latex: '\\\\int_{}^{}', description: 'Integral' },\r\n { display: 'Σ', latex: '\\\\sum_{}^{}', description: 'Summation' },\r\n { display: 'Π', latex: '\\\\prod_{}^{}', description: 'Product' },\r\n ],\r\n },\r\n // 9. HYPERBOLIC TRIG FUNCTIONS\r\n {\r\n id: 'hyperbolic-trig',\r\n name: 'HYPERBOLIC TRIG FUNCTIONS',\r\n functions: [\r\n { display: 'sinh', latex: '\\\\sinh(', description: 'Hyperbolic sine' },\r\n { display: 'cosh', latex: '\\\\cosh(', description: 'Hyperbolic cosine' },\r\n { display: 'tanh', latex: '\\\\tanh(', description: 'Hyperbolic tangent' },\r\n { display: 'csch', latex: '\\\\text{csch}(', description: 'Hyperbolic cosecant' },\r\n { display: 'sech', latex: '\\\\text{sech}(', description: 'Hyperbolic secant' },\r\n { display: 'coth', latex: '\\\\coth(', description: 'Hyperbolic cotangent' },\r\n ],\r\n },\r\n // 10. GEOMETRY\r\n {\r\n id: 'geometry',\r\n name: 'GEOMETRY',\r\n functions: [\r\n { display: 'polygon', latex: '\\\\text{polygon}(', description: 'Polygon' },\r\n { display: 'distance', latex: '\\\\text{distance}(', description: 'Distance' },\r\n { display: 'midpoint', latex: '\\\\text{midpoint}(', description: 'Midpoint' },\r\n ],\r\n },\r\n // 11. CUSTOM COLORS\r\n {\r\n id: 'colors',\r\n name: 'CUSTOM COLORS',\r\n functions: [\r\n { display: 'rgb', latex: '\\\\text{rgb}(', description: 'RGB color' },\r\n { display: 'hsv', latex: '\\\\text{hsv}(', description: 'HSV color' },\r\n { display: 'okhsv', latex: '\\\\text{okhsv}(', description: 'OKHSV color' },\r\n { display: 'oklab', latex: '\\\\text{oklab}(', description: 'OKLAB color' },\r\n { display: 'oklch', latex: '\\\\text{oklch}(', description: 'OKLCH color' },\r\n ],\r\n },\r\n // 12. SOUND\r\n {\r\n id: 'sound',\r\n name: 'SOUND',\r\n functions: [\r\n { display: 'tone', latex: '\\\\text{tone}(', description: 'Generate tone' },\r\n ],\r\n },\r\n // 13. NUMBER THEORY\r\n {\r\n id: 'number-theory',\r\n name: 'NUMBER THEORY',\r\n functions: [\r\n { display: 'lcm', latex: '\\\\text{lcm}(', description: 'Least common multiple' },\r\n { display: 'gcd', latex: '\\\\gcd(', description: 'Greatest common divisor' },\r\n { display: 'mod', latex: '\\\\mod ', description: 'Modulo' },\r\n { display: 'ceil', latex: '\\\\lceil ', description: 'Ceiling' },\r\n { display: 'floor', latex: '\\\\lfloor ', description: 'Floor' },\r\n { display: 'round', latex: '\\\\text{round}(', description: 'Round' },\r\n { display: 'sign', latex: '\\\\text{sign}(', description: 'Sign function' },\r\n { display: 'ⁿ√', latex: '\\\\sqrt[]{}', description: 'Nth root' },\r\n { display: 'nPr', latex: 'P(', description: 'Permutation' },\r\n { display: 'nCr', latex: '\\\\binom{}{}', description: 'Combination' },\r\n ],\r\n },\r\n];\r\n\r\n// ============================================\r\n// HELPER FUNCTIONS\r\n// ============================================\r\n\r\n/**\r\n * Get uppercase/shifted version of ABC keyboard for shift mode\r\n * This handles:\r\n * - Letters become uppercase\r\n * - aᵦ (subscript) becomes aᵇ (superscript)\r\n * Dual-character buttons (!, %, etc.) are handled by blur/emphasis styling\r\n */\r\nexport function getUppercaseAbcKeyboard(): ButtonConfig[][] {\r\n return abcKeyboardRows.map((row) =>\r\n row.map((btn) => {\r\n // Handle letter buttons - uppercase when shifted\r\n if (btn.type === 'letter') {\r\n return {\r\n ...btn,\r\n display: btn.display.toUpperCase(),\r\n latex: btn.latex.toUpperCase(),\r\n };\r\n }\r\n\r\n // Handle subscript -> superscript swap\r\n if (btn.latex === 'SUBSCRIPT') {\r\n return {\r\n ...btn,\r\n display: 'aᵇ',\r\n latex: 'SUPERSCRIPT',\r\n };\r\n }\r\n\r\n // All other buttons remain the same (including dual-char buttons)\r\n return btn;\r\n })\r\n );\r\n}\r\n","import React, { useState, useCallback, useEffect, useRef } from 'react';\r\nimport { useMathContext } from '../MathProvider/MathProvider';\r\nimport {\r\n defaultLeftSection,\r\n defaultMiddleSection,\r\n defaultRightSection,\r\n abcKeyboardRows,\r\n functionCategories,\r\n getUppercaseAbcKeyboard,\r\n} from './keyboardData';\r\nimport type { ButtonConfig, FunctionCategory } from '../../types';\r\nimport './MathKeyboard.css';\r\n\r\n// Debug logging helper\r\nconst DEBUG = false;\r\nconst log = (component: string, action: string, data?: any) => {\r\n if (DEBUG) {\r\n console.log(`[${component}] ${action}`, data !== undefined ? data : '');\r\n }\r\n};\r\n\r\n/**\r\n * Props for the MathKeyboard component\r\n */\r\nexport interface MathKeyboardProps {\r\n /** Whether the keyboard is initially visible */\r\n defaultVisible?: boolean;\r\n /** Callback fired when keyboard visibility changes */\r\n onVisibilityChange?: (visible: boolean) => void;\r\n /** Additional CSS class name */\r\n className?: string;\r\n /** Inline styles */\r\n style?: React.CSSProperties;\r\n}\r\n\r\n/**\r\n * Keyboard modes\r\n */\r\ntype KeyboardMode = 'default' | 'abc';\r\n\r\n/**\r\n * MathKeyboard - A Desmos-style on-screen keyboard for math input\r\n *\r\n * @component\r\n * @example\r\n * ```tsx\r\n * <MathKeyboard defaultVisible={true} />\r\n * ```\r\n */\r\nexport const MathKeyboard: React.FC<MathKeyboardProps> = ({\r\n defaultVisible = false,\r\n onVisibilityChange,\r\n className = '',\r\n style,\r\n}) => {\r\n // State\r\n const [isVisible, setIsVisible] = useState(defaultVisible);\r\n const [keyboardMode, setKeyboardMode] = useState<KeyboardMode>('default');\r\n const [isShiftActive, setIsShiftActive] = useState(false);\r\n const [isFunctionsOpen, setIsFunctionsOpen] = useState(false);\r\n // Mode for next character: 'normal', 'subscript', or 'superscript'\r\n const [nextCharMode, setNextCharMode] = useState<'normal' | 'subscript' | 'superscript'>('normal');\r\n\r\n // Refs\r\n const keyboardRef = useRef<HTMLDivElement>(null);\r\n const functionsRef = useRef<HTMLDivElement>(null);\r\n\r\n // Get context\r\n const mathContext = useMathContext();\r\n log('MathKeyboard', 'context retrieved', { mathContext, hasContext: !!mathContext });\r\n\r\n /**\r\n * Toggle keyboard visibility\r\n */\r\n const toggleKeyboard = useCallback(() => {\r\n setIsVisible((prev) => {\r\n const newValue = !prev;\r\n onVisibilityChange?.(newValue);\r\n if (!newValue) {\r\n setIsFunctionsOpen(false);\r\n }\r\n return newValue;\r\n });\r\n }, [onVisibilityChange]);\r\n\r\n /**\r\n * Handle button click\r\n */\r\n const handleButtonClick = useCallback(\r\n (button: ButtonConfig) => {\r\n log('MathKeyboard', 'handleButtonClick', {\r\n latex: button.latex,\r\n type: button.type,\r\n activeInputId: mathContext?.activeInputId,\r\n hasMathContext: !!mathContext\r\n });\r\n\r\n // Handle dual-character buttons\r\n if (button.dualChar) {\r\n const { primaryLatex, secondaryLatex } = button.dualChar;\r\n const activeLatex = isShiftActive ? secondaryLatex : primaryLatex;\r\n log('MathKeyboard', 'dual-char button', { primaryLatex, secondaryLatex, activeLatex, isShiftActive });\r\n\r\n // Handle SUBSCRIPT/SUPERSCRIPT actions\r\n if (activeLatex === 'SUBSCRIPT') {\r\n setNextCharMode('subscript');\r\n return;\r\n }\r\n if (activeLatex === 'SUPERSCRIPT') {\r\n setNextCharMode('superscript');\r\n return;\r\n }\r\n\r\n // Handle subscript/superscript mode for dual-char buttons\r\n if (nextCharMode !== 'normal') {\r\n const wrapper = nextCharMode === 'subscript' ? `_{${activeLatex}}` : `^{${activeLatex}}`;\r\n log('MathKeyboard', 'inserting with mode wrapper', { wrapper });\r\n mathContext?.insertAtCursor(wrapper);\r\n setNextCharMode('normal');\r\n return;\r\n }\r\n\r\n // Insert the active character's LaTeX\r\n if (mathContext) {\r\n log('MathKeyboard', 'inserting activeLatex via context', { activeLatex });\r\n mathContext.insertAtCursor(activeLatex);\r\n } else {\r\n log('MathKeyboard', 'WARNING: No mathContext for dual-char insertion');\r\n }\r\n return;\r\n }\r\n\r\n // Handle special actions\r\n switch (button.latex) {\r\n case 'ABC_MODE':\r\n setKeyboardMode('abc');\r\n setIsFunctionsOpen(false);\r\n return;\r\n case '123_MODE':\r\n setKeyboardMode('default');\r\n setIsShiftActive(false);\r\n setNextCharMode('normal');\r\n return;\r\n case 'SHIFT':\r\n setIsShiftActive((prev) => !prev);\r\n return;\r\n case 'SUBSCRIPT':\r\n setNextCharMode('subscript');\r\n return;\r\n case 'SUPERSCRIPT':\r\n setNextCharMode('superscript');\r\n return;\r\n case 'FUNCTIONS':\r\n setIsFunctionsOpen((prev) => !prev);\r\n return;\r\n case 'SPEAK':\r\n // No functionality, just for show\r\n return;\r\n case 'ARROW_LEFT':\r\n // Use context to send arrow left command to active input\r\n log('MathKeyboard', 'ARROW_LEFT - sending via context');\r\n if (mathContext) {\r\n mathContext.insertAtCursor('ARROW_LEFT');\r\n }\r\n return;\r\n case 'ARROW_RIGHT':\r\n // Use context to send arrow right command to active input\r\n log('MathKeyboard', 'ARROW_RIGHT - sending via context');\r\n if (mathContext) {\r\n mathContext.insertAtCursor('ARROW_RIGHT');\r\n }\r\n return;\r\n case 'BACKSPACE':\r\n // Use context to send backspace command to active input\r\n log('MathKeyboard', 'BACKSPACE - sending via context');\r\n if (mathContext) {\r\n mathContext.insertAtCursor('BACKSPACE');\r\n }\r\n return;\r\n case 'ENTER':\r\n // Blur the active input (unfocus) - this is handled specially\r\n log('MathKeyboard', 'ENTER - sending blur command');\r\n if (mathContext) {\r\n mathContext.insertAtCursor('ENTER');\r\n }\r\n return;\r\n default:\r\n break;\r\n }\r\n\r\n // Handle subscript/superscript mode for the next character\r\n if (nextCharMode !== 'normal' && (button.type === 'letter' || button.type === 'variable')) {\r\n const wrapper = nextCharMode === 'subscript' ? `_{${button.latex}}` : `^{${button.latex}}`;\r\n log('MathKeyboard', 'inserting letter/variable with mode', { wrapper });\r\n mathContext?.insertAtCursor(wrapper);\r\n setNextCharMode('normal');\r\n // Reset shift after typing\r\n if (isShiftActive) {\r\n setIsShiftActive(false);\r\n }\r\n return;\r\n }\r\n\r\n // Insert LaTeX at cursor\r\n if (mathContext) {\r\n log('MathKeyboard', 'inserting standard latex via context', { latex: button.latex });\r\n mathContext.insertAtCursor(button.latex);\r\n } else {\r\n log('MathKeyboard', 'WARNING: No mathContext for standard insertion', { latex: button.latex });\r\n }\r\n\r\n // Reset shift after typing a letter\r\n if (button.type === 'letter' && isShiftActive) {\r\n setIsShiftActive(false);\r\n }\r\n },\r\n [mathContext, isShiftActive, nextCharMode]\r\n );\r\n\r\n /**\r\n * Handle function button click\r\n * Clicking a function closes only the functions panel, not the keyboard\r\n */\r\n const handleFunctionClick = useCallback(\r\n (latex: string) => {\r\n log('MathKeyboard', 'handleFunctionClick', {\r\n latex,\r\n activeInputId: mathContext?.activeInputId,\r\n hasMathContext: !!mathContext\r\n });\r\n if (mathContext) {\r\n mathContext.insertAtCursor(latex);\r\n } else {\r\n log('MathKeyboard', 'WARNING: No mathContext for function insertion');\r\n }\r\n // Close only the functions panel, keyboard stays open\r\n setIsFunctionsOpen(false);\r\n },\r\n [mathContext]\r\n );\r\n\r\n /**\r\n * Handle click outside to close keyboard\r\n */\r\n useEffect(() => {\r\n const handleClickOutside = (event: MouseEvent) => {\r\n if (!isVisible) return;\r\n\r\n const target = event.target as HTMLElement;\r\n\r\n // Check if click is inside keyboard\r\n if (keyboardRef.current?.contains(target)) return;\r\n\r\n // Check if click is on a math input\r\n if (target.closest('.mathex-input')) return;\r\n\r\n // Close keyboard\r\n setIsVisible(false);\r\n setIsFunctionsOpen(false);\r\n onVisibilityChange?.(false);\r\n };\r\n\r\n document.addEventListener('mousedown', handleClickOutside);\r\n return () => {\r\n document.removeEventListener('mousedown', handleClickOutside);\r\n };\r\n }, [isVisible, onVisibilityChange]);\r\n\r\n /**\r\n * Prevent focus stealing - CRITICAL for keyboard to work properly\r\n * This prevents the button click from moving focus away from the MathInput\r\n */\r\n const preventFocusLoss = useCallback((e: React.MouseEvent) => {\r\n e.preventDefault();\r\n log('MathKeyboard', 'preventFocusLoss - mousedown prevented');\r\n }, []);\r\n\r\n /**\r\n * Render a single button\r\n */\r\n const renderButton = (button: ButtonConfig, index: number) => {\r\n const buttonClasses = [\r\n 'dcg-keypad-btn-container',\r\n button.size === 'wide' && 'dcg-wide',\r\n button.size === 'extra-wide' && 'dcg-extra-wide',\r\n ]\r\n .filter(Boolean)\r\n .join(' ');\r\n\r\n const innerClasses = [\r\n 'dcg-keypad-btn',\r\n button.style === 'blue' && 'dcg-btn-blue',\r\n button.style === 'gray-light' && 'dcg-btn-light-gray',\r\n button.style === 'white' && 'dcg-btn-white',\r\n button.latex === 'SHIFT' && isShiftActive && 'dcg-active',\r\n button.latex === 'SUBSCRIPT' && nextCharMode === 'subscript' && 'dcg-active',\r\n button.latex === 'SUPERSCRIPT' && nextCharMode === 'superscript' && 'dcg-active',\r\n ]\r\n .filter(Boolean)\r\n .join(' ');\r\n\r\n // Render dual-character buttons with blur/emphasis styling\r\n if (button.dualChar) {\r\n const { primary, secondary } = button.dualChar;\r\n return (\r\n <div key={index} className={buttonClasses}>\r\n <button\r\n className={innerClasses}\r\n onClick={() => handleButtonClick(button)}\r\n onMouseDown={preventFocusLoss}\r\n onTouchStart={preventFocusLoss as any}\r\n type=\"button\"\r\n >\r\n <span className=\"dcg-keypad-btn-content dcg-dual-char\">\r\n <span className={`dcg-dual-primary ${isShiftActive ? 'dcg-blurred' : 'dcg-clear'}`}>\r\n {primary}\r\n </span>\r\n <span className={`dcg-dual-secondary ${isShiftActive ? 'dcg-clear' : 'dcg-blurred'}`}>\r\n {secondary}\r\n </span>\r\n </span>\r\n </button>\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div key={index} className={buttonClasses}>\r\n <button\r\n className={innerClasses}\r\n onClick={() => handleButtonClick(button)}\r\n onMouseDown={preventFocusLoss}\r\n onTouchStart={preventFocusLoss as any}\r\n type=\"button\"\r\n >\r\n <span className=\"dcg-keypad-btn-content\">{button.display}</span>\r\n </button>\r\n </div>\r\n );\r\n };\r\n\r\n /**\r\n * Render default keyboard (numbers + variables)\r\n */\r\n const renderDefaultKeyboard = () => (\r\n <div className=\"dcg-basic-keypad dcg-default-mode\">\r\n <div className=\"dcg-audio-keypad-container\">\r\n {/* Left section */}\r\n <div className=\"dcg-audio-keypad-column dcg-left-section\">\r\n {defaultLeftSection.map((row, rowIndex) => (\r\n <div key={rowIndex} className=\"dcg-keypad-row\">\r\n {row.map((button, btnIndex) => renderButton(button, btnIndex))}\r\n </div>\r\n ))}\r\n </div>\r\n\r\n {/* Middle section (number pad) */}\r\n <div className=\"dcg-audio-keypad-column dcg-middle-section\">\r\n {defaultMiddleSection.map((row, rowIndex) => (\r\n <div key={rowIndex} className=\"dcg-keypad-row\">\r\n {row.map((button, btnIndex) => renderButton(button, btnIndex))}\r\n </div>\r\n ))}\r\n </div>\r\n\r\n {/* Right section (functions, navigation) */}\r\n <div className=\"dcg-audio-keypad-column dcg-right-section\">\r\n {defaultRightSection.map((row, rowIndex) => (\r\n <div key={rowIndex} className=\"dcg-keypad-row\">\r\n {row.map((button, btnIndex) => renderButton(button, btnIndex))}\r\n </div>\r\n ))}\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n\r\n /**\r\n * Render ABC keyboard\r\n */\r\n const renderAbcKeyboard = () => {\r\n const rows = isShiftActive ? getUppercaseAbcKeyboard() : abcKeyboardRows;\r\n\r\n return (\r\n <div className=\"dcg-basic-keypad dcg-abc-mode\">\r\n {rows.map((row, rowIndex) => (\r\n <div key={rowIndex} className={`dcg-keypad-row dcg-abc-row-${rowIndex}`}>\r\n {row.map((button, btnIndex) => renderButton(button, btnIndex))}\r\n </div>\r\n ))}\r\n </div>\r\n );\r\n };\r\n\r\n /**\r\n * Render functions panel\r\n */\r\n const renderFunctionsPanel = () => (\r\n <div\r\n ref={functionsRef}\r\n className={`dcg-functions-popover ${isFunctionsOpen ? 'dcg-visible' : ''}`}\r\n >\r\n <div className=\"dcg-popover-interior\">\r\n {functionCategories.map((category: FunctionCategory) => (\r\n <div key={category.id} className=\"dcg-keypad-keys-section\">\r\n <div className=\"dcg-section-heading\">{category.name}</div>\r\n <div className=\"dcg-keypad-keys-buttons\">\r\n {category.functions.map((func, index) => (\r\n <div key={index} className=\"dcg-keypad-btn-container dcg-function-btn\">\r\n <button\r\n className=\"dcg-keypad-btn dcg-btn-white\"\r\n onClick={() => handleFunctionClick(func.latex)}\r\n onMouseDown={preventFocusLoss}\r\n onTouchStart={preventFocusLoss as any}\r\n title={func.description}\r\n type=\"button\"\r\n >\r\n <span className=\"dcg-keypad-btn-content\">{func.display}</span>\r\n </button>\r\n </div>\r\n ))}\r\n </div>\r\n </div>\r\n ))}\r\n </div>\r\n </div>\r\n );\r\n\r\n /**\r\n * Render toggle button (when keyboard is hidden)\r\n */\r\n const renderToggleButton = () => (\r\n <div className=\"dcg-show-keypad-container\">\r\n <button\r\n className=\"dcg-show-keypad dcg-btn-light-gray\"\r\n onClick={toggleKeyboard}\r\n type=\"button\"\r\n aria-label={isVisible ? 'Hide keyboard' : 'Show keyboard'}\r\n >\r\n <span className=\"dcg-icon-keyboard\">⌨</span>\r\n <span className={`dcg-icon-caret ${isVisible ? 'dcg-icon-caret-down' : 'dcg-icon-caret-up'}`}>\r\n {isVisible ? '▼' : '▲'}\r\n </span>\r\n </button>\r\n </div>\r\n );\r\n\r\n /**\r\n * Render minimize button (when keyboard is visible)\r\n */\r\n const renderMinimizeButton = () => (\r\n <div className=\"dcg-minimize-keypad-container\">\r\n <button\r\n className=\"dcg-minimize-keypad dcg-btn-light-gray\"\r\n onClick={toggleKeyboard}\r\n type=\"button\"\r\n aria-label=\"Hide keyboard\"\r\n >\r\n <span className=\"dcg-icon-keyboard\">⌨</span>\r\n <span className=\"dcg-icon-caret dcg-icon-caret-down\">▼</span>\r\n </button>\r\n </div>\r\n );\r\n\r\n return (\r\n <div\r\n ref={keyboardRef}\r\n className={`dcg-keypad ${isVisible ? 'dcg-visible' : 'dcg-hidden'} ${className}`}\r\n style={style}\r\n >\r\n {/* Toggle button - always visible at bottom-left when keyboard is hidden */}\r\n {!isVisible && renderToggleButton()}\r\n\r\n {/* Main keyboard container */}\r\n {isVisible && (\r\n <div className=\"dcg-keys-container\">\r\n {/* Minimize button */}\r\n {renderMinimizeButton()}\r\n\r\n {/* Keys background */}\r\n <div className=\"dcg-keys-background\">\r\n <div className=\"dcg-keys\">\r\n {/* Render current keyboard mode */}\r\n {keyboardMode === 'default' ? renderDefaultKeyboard() : renderAbcKeyboard()}\r\n </div>\r\n </div>\r\n\r\n {/* Functions panel */}\r\n {renderFunctionsPanel()}\r\n </div>\r\n )}\r\n </div>\r\n );\r\n};\r\n\r\nMathKeyboard.displayName = 'MathKeyboard';\r\n"],"names":["log","component","action","data","MathContext","createContext","useMathContext","useContext","MathProvider","children","theme","activeInputId","setActiveInputId","useState","activeInputIdRef","useRef","inputCallbacksRef","registerInput","useCallback","id","updateCallback","unregisterInput","current","setActiveInput","insertAtCursor","latex","currentActiveId","contextValue","themeAttr","jsx","getMQ","MathInput","controlledValue","defaultValue","onChange","placeholder","disabled","className","style","autoFocus","readOnly","onError","isControlled","uncontrolledValue","setUncontrolledValue","isFocused","setIsFocused","mathFieldRef","containerRef","inputId","useMemo","mathContext","mathContextRef","inputIdRef","useEffect","MQ","config","mathField","newLatex","element","handleFocusIn","currentInputId","currentContext","handleFocusOut","error","handleFocus","handleKeyboardInsertion","insertedLatex","defaultLeftSection","defaultMiddleSection","defaultRightSection","abcKeyboardRows","functionCategories","getUppercaseAbcKeyboard","row","btn","MathKeyboard","defaultVisible","onVisibilityChange","isVisible","setIsVisible","keyboardMode","setKeyboardMode","isShiftActive","setIsShiftActive","isFunctionsOpen","setIsFunctionsOpen","nextCharMode","setNextCharMode","keyboardRef","functionsRef","toggleKeyboard","prev","newValue","handleButtonClick","button","primaryLatex","secondaryLatex","activeLatex","wrapper","handleFunctionClick","handleClickOutside","event","target","preventFocusLoss","renderButton","index","buttonClasses","innerClasses","primary","secondary","jsxs","renderDefaultKeyboard","rowIndex","btnIndex","renderAbcKeyboard","rows","renderFunctionsPanel","category","func","renderToggleButton","renderMinimizeButton"],"mappings":"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"}
|
package/dist/mathex.css
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.mathex-input{position:relative;min-height:var(--math-input-min-height, 48px);padding:var(--math-input-padding, 12px 16px);background:var(--math-background, #FFFFFF);border:2px solid var(--math-border-color, #D0D0D0);border-left:3px solid transparent;border-radius:var(--math-border-radius, 4px);font-family:var(--math-font, "KaTeX_Main", "Times New Roman", serif);font-size:var(--math-font-size, 18px);line-height:1.6;cursor:text;transition:border-color .2s ease,background-color .2s ease;box-sizing:border-box}.mathex-input:not(.mathex-input--disabled):hover{border-color:var(--math-border-light, #BCBCBC)}.mathex-input--focused{border-left-color:var(--math-primary-color, #2F7DEF);outline:none}.mathex-input--disabled{background:var(--math-bg-light-gray, #F5F5F5);cursor:not-allowed;opacity:.6}.mathex-mathquill-container{min-height:24px;position:relative}.mathex-input .mq-editable-field{border:none!important;padding:0!important;margin:0!important;min-height:24px;background:transparent!important}.mathex-input .mq-root-block{color:var(--math-text-color, #000000)!important}.mathex-input .mq-cursor{border-left:1px solid var(--math-text-color, #000000)!important}.mathex-input .mq-selection{background:var(--math-selection-bg, #C9E1FF)!important}.mathex-input .mq-non-leaf,.mathex-input .mq-scaled{color:var(--math-text-color, #000000)}.mathex-mathquill-container[data-placeholder]:has(.mq-empty):before,.mathex-mathquill-container[data-placeholder]:not(:has(*)):before{content:attr(data-placeholder);color:var(--math-text-light, #999999);font-style:italic;pointer-events:none;position:absolute;left:0;top:0}[data-theme=dark] .mathex-input .mq-root-block,[data-theme=dark] .mathex-input .mq-non-leaf,[data-theme=dark] .mathex-input .mq-scaled{color:var(--math-text-color)!important}[data-theme=dark] .mathex-input .mq-cursor{border-left-color:var(--math-text-color)!important}[data-theme=dark] .mathex-input .mq-selection{background:var(--math-selection-bg)!important}@media(max-width:768px){.mathex-input{font-size:16px;min-height:44px;padding:10px 14px}}:root{--dcg-accent-color: #2f72dc;--dcg-accent-color-shaded-10: #2457a8;--dcg-accent-color-shaded-20: #193d75;--dcg-custom-background-color: #fff;--dcg-custom-background-color-shaded: #eff2f3;--dcg-custom-text-color: #000}[data-theme=dark]{--dcg-accent-color: #5B9CFF;--dcg-accent-color-shaded-10: #4A8AE8;--dcg-accent-color-shaded-20: #3978D1;--dcg-custom-background-color: #2D2D2D;--dcg-custom-background-color-shaded: #1E1E1E;--dcg-custom-text-color: #FFFFFF}.dcg-keypad{position:fixed;bottom:0;left:0;right:0;z-index:1000;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,sans-serif;font-size:16px;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.dcg-keypad.dcg-hidden{pointer-events:none}.dcg-keypad.dcg-hidden .dcg-show-keypad-container{pointer-events:auto}.dcg-show-keypad-container{z-index:6;position:fixed;bottom:5px;left:5px;animation:dcg-fadeIn-show-keypad .6s}.dcg-show-keypad{padding:4px 14px;display:flex;align-items:center;gap:8px;cursor:pointer;border-radius:5px;border:1px solid #ccc;background:linear-gradient(#f6f6f6,#f0f0f0);box-shadow:inset 0 1px #ffffff40,inset 0 -1px #00000005;transition:background .2s}.dcg-show-keypad:hover{background:#ededed;border-color:#bbb}.dcg-show-keypad:active{background:#e0e0e0;border-color:#949494;box-shadow:none}.dcg-icon-keyboard{font-size:175%;line-height:1}.dcg-icon-caret{font-size:75%;line-height:2rem}.dcg-minimize-keypad-container{position:absolute;top:-2.5rem;left:-1px;z-index:10}.dcg-minimize-keypad{padding:.25rem 1.25rem;border-radius:5px 5px 0 0;display:flex;align-items:center;gap:8px;cursor:pointer;border:1px solid #ccc;border-bottom:none;background:linear-gradient(#f6f6f6,#f0f0f0);box-shadow:inset 0 1px #ffffff40,inset 0 -1px #00000005;transition:background .2s}.dcg-minimize-keypad:hover{background:#ededed;border-color:#bbb}.dcg-minimize-keypad:active{background:#e0e0e0;border-color:#949494;box-shadow:none}.dcg-keys-container{position:relative;width:100%;animation:dcg-slideUp .3s ease-out}.dcg-keys-background{background:var(--dcg-custom-background-color, #f5f5f5);border-top:1px solid #ccc;padding:8px 0}.dcg-keys{position:relative;width:100%;max-width:835px;margin:auto;text-align:center}.dcg-basic-keypad{display:flex;justify-content:center}.dcg-audio-keypad-container{display:flex;flex:1;justify-content:center;gap:4px}.dcg-audio-keypad-column{display:flex;flex-direction:column;gap:0}.dcg-left-section,.dcg-middle-section{min-width:240px}.dcg-right-section{min-width:160px}.dcg-keypad-row{display:flex;justify-content:center;gap:0}.dcg-keypad-btn-container{position:relative;width:60px;height:50px;flex-shrink:0}.dcg-keypad-btn-container.dcg-wide{width:75px}.dcg-keypad-btn-container.dcg-extra-wide{width:100%;min-width:140px}.dcg-keypad-btn{position:absolute;inset:2px;display:flex;flex-flow:row;align-items:center;justify-content:center;padding:0;border-radius:5px;cursor:pointer;font-size:16px;font-family:inherit;transition:background .15s,border-color .15s;-webkit-user-select:none;user-select:none}.dcg-keypad-btn-content{text-align:center;flex:1;pointer-events:none;font-weight:400}.dcg-keypad-btn.dcg-btn-white{color:var(--dcg-custom-text-color, #000);box-shadow:inset 0 1px #fff6,inset 0 -1px #00000005;background:linear-gradient(#fff,#f9f9f9);border:1px solid rgba(0,0,0,.1)}.dcg-keypad-btn.dcg-btn-white:hover{background:#f5f5f5;border-color:#00000026}.dcg-keypad-btn.dcg-btn-white:active{background:#ebebeb;border-color:#0003;box-shadow:none}.dcg-keypad-btn.dcg-btn-light-gray{color:#000;box-shadow:inset 0 1px #ffffff40,inset 0 -1px #00000005;background:linear-gradient(#f6f6f6,#f0f0f0);border:1px solid rgba(0,0,0,.1)}.dcg-keypad-btn.dcg-btn-light-gray:hover{background:#ededed;border:1px solid rgba(0,0,0,.13)}.dcg-keypad-btn.dcg-btn-light-gray:active,.dcg-keypad-btn.dcg-btn-light-gray.dcg-active{background:#e0e0e0;border:1px solid rgba(0,0,0,.15);box-shadow:none}.dcg-keypad-btn.dcg-btn-blue{color:#fff;background:var(--dcg-accent-color, #2f72dc);border:1px solid transparent;box-shadow:inset 0 1px #ffffff1a,inset 0 -1px #0000000a}.dcg-keypad-btn.dcg-btn-blue:hover{background:var(--dcg-accent-color-shaded-10, #2457a8)}.dcg-keypad-btn.dcg-btn-blue:active{background:var(--dcg-accent-color-shaded-20, #193d75);box-shadow:none}.dcg-abc-mode{display:flex;flex-direction:column;align-items:center;padding:8px}.dcg-abc-mode .dcg-keypad-row{justify-content:center}.dcg-abc-row-1{padding-left:20px}.dcg-abc-row-2 .dcg-keypad-btn-container:first-child,.dcg-abc-row-2 .dcg-keypad-btn-container:last-child{width:75px}.dcg-abc-row-3 .dcg-keypad-btn-container:first-child{width:100px}.dcg-abc-row-3 .dcg-keypad-btn-container:last-child{width:120px}.dcg-functions-popover{position:absolute;right:8px;top:-306px;opacity:0;visibility:hidden;transform:translate(20px);transition:opacity .2s,transform .2s,visibility .2s;z-index:100}.dcg-functions-popover.dcg-visible{opacity:1;visibility:visible;transform:translate(0)}.dcg-popover-interior{background-color:var(--dcg-custom-background-color, #fff);color:var(--dcg-custom-text-color, #000);padding:0;width:310px;height:306px;overflow-y:auto;border:1px solid #ccc;border-radius:5px;box-shadow:0 2px 10px #00000026}.dcg-popover-interior::-webkit-scrollbar{width:8px}.dcg-popover-interior::-webkit-scrollbar-track{background:#f1f1f1;border-radius:4px}.dcg-popover-interior::-webkit-scrollbar-thumb{background:#c1c1c1;border-radius:4px}.dcg-popover-interior::-webkit-scrollbar-thumb:hover{background:#a8a8a8}.dcg-keypad-keys-section{border:1px solid transparent}.dcg-keypad-keys-section+.dcg-keypad-keys-section{margin-top:8px}.dcg-section-heading{color:var(--dcg-custom-text-color, #666);text-transform:uppercase;font-size:75%;text-align:left;padding:5px 8px;position:sticky;top:0;background:var(--dcg-custom-background-color, #fff);z-index:2;font-weight:600;letter-spacing:.5px}.dcg-keypad-keys-buttons{display:flex;flex-wrap:wrap;margin-bottom:7px}.dcg-function-btn{width:33.3%;height:42px;margin-bottom:-5px;overflow:hidden}.dcg-function-btn .dcg-keypad-btn{font-size:80%!important;white-space:nowrap;color:var(--dcg-custom-text-color, #000)}@keyframes dcg-fadeIn-show-keypad{0%{opacity:0}to{opacity:1}}@keyframes dcg-slideUp{0%{transform:translateY(100%);opacity:0}to{transform:translateY(0);opacity:1}}@media(max-width:900px){.dcg-keypad-btn-container{width:50px;height:45px}.dcg-keypad-btn{font-size:14px}.dcg-left-section,.dcg-middle-section{min-width:200px}.dcg-right-section{min-width:120px}}@media(max-width:700px){.dcg-audio-keypad-container{flex-wrap:wrap}.dcg-keypad-btn-container{width:45px;height:40px}.dcg-keypad-btn{font-size:13px}.dcg-functions-popover{right:4px;width:280px}.dcg-popover-interior{width:280px}}.dcg-keypad-btn-container.dcg-disabled{opacity:.5;pointer-events:none}.dcg-keypad-btn-container.dcg-disabled .dcg-keypad-btn{cursor:default}.dcg-dual-char{display:flex;align-items:center;justify-content:center;gap:6px}.dcg-dual-primary,.dcg-dual-secondary{transition:opacity .15s ease,filter .15s ease}.dcg-dual-primary.dcg-clear,.dcg-dual-secondary.dcg-clear{opacity:1;filter:none;color:var(--dcg-custom-text-color, #000)}.dcg-dual-primary.dcg-blurred,.dcg-dual-secondary.dcg-blurred{opacity:.35;filter:none;color:var(--dcg-custom-text-color, #666)}[data-theme=dark] .dcg-show-keypad,[data-theme=dark] .dcg-minimize-keypad{background:linear-gradient(#3d3d3d,#2d2d2d);border-color:#555;color:var(--dcg-custom-text-color)}[data-theme=dark] .dcg-show-keypad:hover,[data-theme=dark] .dcg-minimize-keypad:hover{background:#4d4d4d;border-color:#666}[data-theme=dark] .dcg-show-keypad:active,[data-theme=dark] .dcg-minimize-keypad:active{background:#3d3d3d;border-color:#444}[data-theme=dark] .dcg-keys-background{background:var(--dcg-custom-background-color-shaded);border-top-color:#444}[data-theme=dark] .dcg-keypad-btn.dcg-btn-white{background:linear-gradient(#3d3d3d,#2d2d2d);border-color:#555;color:var(--dcg-custom-text-color)}[data-theme=dark] .dcg-keypad-btn.dcg-btn-white:hover{background:#4d4d4d;border-color:#666}[data-theme=dark] .dcg-keypad-btn.dcg-btn-white:active{background:#3d3d3d;border-color:#444}[data-theme=dark] .dcg-keypad-btn.dcg-btn-light-gray{background:linear-gradient(#444,#3d3d3d);border-color:#555;color:var(--dcg-custom-text-color)}[data-theme=dark] .dcg-keypad-btn.dcg-btn-light-gray:hover{background:#4d4d4d;border-color:#666}[data-theme=dark] .dcg-keypad-btn.dcg-btn-light-gray:active,[data-theme=dark] .dcg-keypad-btn.dcg-btn-light-gray.dcg-active{background:#3d3d3d;border-color:#444}[data-theme=dark] .dcg-popover-interior{background-color:var(--dcg-custom-background-color);border-color:#444;box-shadow:0 2px 10px #00000080}[data-theme=dark] .dcg-popover-interior::-webkit-scrollbar-track{background:#1e1e1e}[data-theme=dark] .dcg-popover-interior::-webkit-scrollbar-thumb{background:#555}[data-theme=dark] .dcg-popover-interior::-webkit-scrollbar-thumb:hover{background:#666}
|