@lax-wp/design-system 0.13.33-beta.4 → 0.13.33-beta.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/forms/base-input-field/BaseInputField.cjs.js +2 -2
- package/dist/components/forms/base-input-field/BaseInputField.cjs.js.map +1 -1
- package/dist/components/forms/base-input-field/BaseInputField.es.js +20 -20
- package/dist/components/forms/base-input-field/BaseInputField.es.js.map +1 -1
- package/dist/components/forms/creatable-select/CreatableSelect.cjs.js +1 -1
- package/dist/components/forms/creatable-select/CreatableSelect.cjs.js.map +1 -1
- package/dist/components/forms/creatable-select/CreatableSelect.es.js +7 -7
- package/dist/components/forms/creatable-select/CreatableSelect.es.js.map +1 -1
- package/dist/components/forms/currency-input/CurrencyInputField.cjs.js +1 -1
- package/dist/components/forms/currency-input/CurrencyInputField.cjs.js.map +1 -1
- package/dist/components/forms/currency-input/CurrencyInputField.es.js +12 -12
- package/dist/components/forms/currency-input/CurrencyInputField.es.js.map +1 -1
- package/dist/components/forms/date-time-field/DateTimeField.cjs.js +1 -1
- package/dist/components/forms/date-time-field/DateTimeField.cjs.js.map +1 -1
- package/dist/components/forms/date-time-field/DateTimeField.es.js +1 -1
- package/dist/components/forms/date-time-field/DateTimeField.es.js.map +1 -1
- package/dist/components/forms/dynamic-data-input/DynamicDataInput.cjs.js +1 -1
- package/dist/components/forms/dynamic-data-input/DynamicDataInput.cjs.js.map +1 -1
- package/dist/components/forms/dynamic-data-input/DynamicDataInput.es.js +7 -7
- package/dist/components/forms/dynamic-data-input/DynamicDataInput.es.js.map +1 -1
- package/dist/components/forms/dynamic-data-input/DynamicDataInputField.cjs.js +1 -1
- package/dist/components/forms/dynamic-data-input/DynamicDataInputField.cjs.js.map +1 -1
- package/dist/components/forms/dynamic-data-input/DynamicDataInputField.es.js +1 -1
- package/dist/components/forms/dynamic-data-input/DynamicDataInputField.es.js.map +1 -1
- package/dist/components/forms/formula-input/FormulaInput.cjs.js +1 -1
- package/dist/components/forms/formula-input/FormulaInput.cjs.js.map +1 -1
- package/dist/components/forms/formula-input/FormulaInput.es.js +10 -10
- package/dist/components/forms/formula-input/FormulaInput.es.js.map +1 -1
- package/dist/components/forms/input-field/InputField.cjs.js.map +1 -1
- package/dist/components/forms/input-field/InputField.es.js.map +1 -1
- package/dist/components/forms/master-data-input/MasterDataInputField.cjs.js +1 -1
- package/dist/components/forms/master-data-input/MasterDataInputField.cjs.js.map +1 -1
- package/dist/components/forms/master-data-input/MasterDataInputField.es.js +1 -1
- package/dist/components/forms/master-data-input/MasterDataInputField.es.js.map +1 -1
- package/dist/components/forms/percentage-input/PercentageInputField.cjs.js +2 -2
- package/dist/components/forms/percentage-input/PercentageInputField.cjs.js.map +1 -1
- package/dist/components/forms/percentage-input/PercentageInputField.es.js +19 -19
- package/dist/components/forms/percentage-input/PercentageInputField.es.js.map +1 -1
- package/dist/components/forms/select-field/SelectField.cjs.js +2 -2
- package/dist/components/forms/select-field/SelectField.cjs.js.map +1 -1
- package/dist/components/forms/select-field/SelectField.es.js +1 -1
- package/dist/components/forms/select-field/SelectField.es.js.map +1 -1
- package/dist/components/forms/text-area-field/TextAreaField.cjs.js +1 -1
- package/dist/components/forms/text-area-field/TextAreaField.cjs.js.map +1 -1
- package/dist/components/forms/text-area-field/TextAreaField.es.js +14 -14
- package/dist/components/forms/text-area-field/TextAreaField.es.js.map +1 -1
- package/dist/components/forms/toggle/Toggle.cjs.js +1 -1
- package/dist/components/forms/toggle/Toggle.cjs.js.map +1 -1
- package/dist/components/forms/toggle/Toggle.es.js +62 -56
- package/dist/components/forms/toggle/Toggle.es.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FormulaInput.es.js","sources":["../../../../src/components/forms/formula-input/FormulaInput.tsx"],"sourcesContent":["import { Instance as PopperInstance, createPopper } from '@popperjs/core';\nimport cn from 'classnames';\nimport React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport ContentEditable, { ContentEditableEvent } from 'react-contenteditable';\nimport { createPortal } from 'react-dom';\nimport { VisibilityOffOutlined, VisibilityOutlined } from '@mui/icons-material';\n\nimport { Typography } from '../../data-display/typography/Typography';\nimport IconButton from '../../button/IconButton';\nimport Tooltip from '../../tooltip/Tooltip';\nimport { HelpIcon } from '../../icons/HelpIcon';\nimport { useOutsideClick } from '../../../hooks/useOutsideClick';\nimport { convertFromPills, convertToPills, getTextBeforeCursor } from './utils';\nimport { InputLabel } from '../shared/InputLabel';\n\nexport interface FormulaInputProps {\n /** Current value of the input */\n value: string;\n /** Callback when value changes */\n onChange: (value: string) => void;\n /** Callback when input receives focus */\n onFocus?: () => void;\n /** Callback when input loses focus */\n onBlur?: () => void;\n /** Label for the input field */\n label?: string;\n /** Unique identifier for the input */\n id: string;\n /** Whether the field is required */\n required?: boolean;\n /** Tooltip text displayed next to the label */\n tooltip?: string;\n /** Placeholder text */\n placeholder?: string;\n /** Whether the input is disabled */\n disabled?: boolean;\n /** Error message to display */\n errorMessage?: string;\n /** Width of the input */\n width?: string;\n /** List of suggestions for autocomplete */\n suggestions?: string[];\n /** Whether to show the raw value instead of pills */\n showRawValue?: boolean;\n}\n\n/**\n * FormulaInput component for entering formulas with variable suggestions\n * Variables are displayed as pills and can be inserted using @ trigger\n */\nconst FormulaInput: React.FC<FormulaInputProps> = ({\n value = '',\n onChange,\n onFocus,\n onBlur,\n label,\n id,\n required: isRequired,\n tooltip,\n placeholder,\n disabled,\n errorMessage,\n width = '100%',\n suggestions = [],\n showRawValue: showRawValueProp = false,\n}) => {\n const contentRef = useRef<HTMLElement & { isFocused?: boolean }>(null);\n const inputWrapperRef = useRef<HTMLDivElement>(null);\n const suggestionMenuRef = useRef<HTMLDivElement>(null);\n const suggestionRefs = useRef<(HTMLDivElement | null)[]>([]);\n const popperInstanceRef = useRef<PopperInstance | null>(null);\n const [showSuggestions, setShowSuggestions] = useState(false);\n const [searchTerm, setSearchTerm] = useState('');\n const [selectedIndex, setSelectedIndex] = useState(0);\n const [showRawValue, setShowRawValue] = useState(showRawValueProp);\n\n // Use refs to track current state for event handlers\n const showSuggestionsRef = useRef(showSuggestions);\n const filteredSuggestionsRef = useRef<string[]>([]);\n const selectedIndexRef = useRef(selectedIndex);\n const valueRef = useRef(value);\n\n // Keep refs in sync with state\n useEffect(() => {\n showSuggestionsRef.current = showSuggestions;\n }, [showSuggestions]);\n\n useEffect(() => {\n selectedIndexRef.current = selectedIndex;\n }, [selectedIndex]);\n\n useEffect(() => {\n valueRef.current = value;\n }, [value]);\n\n // Close suggestions when clicking outside\n useOutsideClick({\n ref: suggestionMenuRef,\n handler: () => {\n if (showSuggestions) {\n setShowSuggestions(false);\n }\n },\n });\n\n // Filter suggestions based on search term\n const filteredSuggestions = useMemo(() => {\n if (!searchTerm) return suggestions;\n\n const lowerSearchTerm = searchTerm.toLowerCase();\n return suggestions.filter((suggestion) => suggestion.toLowerCase().includes(lowerSearchTerm));\n }, [suggestions, searchTerm]);\n\n // Keep filtered suggestions ref in sync\n useEffect(() => {\n filteredSuggestionsRef.current = filteredSuggestions;\n }, [filteredSuggestions]);\n\n // Reset selected index when filtered suggestions change\n useEffect(() => {\n setSelectedIndex(0);\n }, [filteredSuggestions]);\n\n // Scroll selected suggestion into view\n useEffect(() => {\n if (showSuggestions && suggestionRefs.current[selectedIndex]) {\n suggestionRefs.current[selectedIndex]?.scrollIntoView({\n block: 'nearest',\n behavior: 'smooth',\n });\n }\n }, [selectedIndex, showSuggestions]);\n\n // Setup Popper for dynamic positioning\n useEffect(() => {\n if (showSuggestions && inputWrapperRef.current && suggestionMenuRef.current) {\n // Create popper instance with auto placement\n popperInstanceRef.current = createPopper(inputWrapperRef.current, suggestionMenuRef.current, {\n placement: 'bottom-start',\n strategy: 'fixed',\n modifiers: [\n {\n name: 'flip',\n options: {\n fallbackPlacements: ['top-start', 'bottom-start'],\n },\n },\n {\n name: 'preventOverflow',\n options: {\n boundary: 'viewport',\n padding: 8,\n },\n },\n {\n name: 'offset',\n options: {\n offset: [0, 4],\n },\n },\n ],\n });\n\n return () => {\n if (popperInstanceRef.current) {\n popperInstanceRef.current.destroy();\n popperInstanceRef.current = null;\n }\n };\n }\n }, [showSuggestions]);\n\n const handleChange = useCallback(\n (event: ContentEditableEvent) => {\n const rawValue = convertFromPills(event.target.value);\n onChange(rawValue);\n\n // Check if user typed @ (trigger for suggestions)\n const textBeforeCursor = getTextBeforeCursor();\n const lastAtSymbol = textBeforeCursor.lastIndexOf('@');\n\n if (lastAtSymbol !== -1) {\n // Get text after the @ symbol\n const textAfterAt = textBeforeCursor.slice(lastAtSymbol + 1);\n\n // Check if there's a space after @, which would end the suggestion context\n const hasSpace = textAfterAt.includes(' ');\n\n if (!hasSpace) {\n // We're in suggestion mode - show suggestions filtered by text after @\n setSearchTerm(textAfterAt);\n setShowSuggestions(true);\n } else {\n setShowSuggestions(false);\n }\n } else {\n setShowSuggestions(false);\n }\n },\n [onChange],\n );\n\n const handleFocus = useCallback(() => {\n if (contentRef.current) {\n contentRef.current.isFocused = true;\n }\n onFocus?.();\n }, [onFocus]);\n\n const handleBlur = useCallback(\n (event: React.FocusEvent) => {\n if (contentRef.current) {\n contentRef.current.isFocused = false;\n }\n\n // Check if the blur is due to clicking on a suggestion\n const relatedTarget = event.relatedTarget as HTMLElement;\n if (relatedTarget && suggestionMenuRef.current?.contains(relatedTarget)) {\n // Don't close suggestions if clicking on a suggestion\n return;\n }\n\n // Delay closing suggestions to allow click events to register\n setTimeout(() => {\n setShowSuggestions(false);\n }, 200);\n onBlur?.();\n },\n [onBlur],\n );\n\n const insertSuggestion = useCallback(\n (suggestion: string) => {\n if (!contentRef.current) return;\n\n // IMPORTANT: Use the value prop (not innerText) to preserve existing {{}} syntax\n // innerText only shows display text and loses the {{}} markers from pills\n const currentValue = valueRef.current;\n\n // Find the last occurrence of @ (trigger symbol) in the raw value\n const lastAtSymbol = currentValue.lastIndexOf('@');\n\n if (lastAtSymbol !== -1) {\n // Find where the @ trigger ends (space or end of string)\n const afterAt = currentValue.slice(lastAtSymbol + 1);\n const spaceIndex = afterAt.search(/\\s/);\n\n let endPosition: number;\n if (spaceIndex === -1) {\n // No space found, the incomplete variable goes to the end\n endPosition = currentValue.length;\n } else {\n // Space found, replace up to the space\n endPosition = lastAtSymbol + 1 + spaceIndex;\n }\n\n // Build the new value preserving all existing {{}} syntax\n // Replace @searchTerm with {{suggestion}}\n const beforeAt = currentValue.slice(0, lastAtSymbol);\n const afterCursor = currentValue.slice(endPosition);\n const newValue = `${beforeAt}{{${suggestion}}}${afterCursor}`;\n\n // Update through onChange\n onChange(newValue);\n\n // Close suggestions\n setShowSuggestions(false);\n setSearchTerm('');\n\n // Refocus the input after React updates\n setTimeout(() => {\n contentRef.current?.focus();\n }, 0);\n }\n },\n [onChange],\n );\n\n const handleKeyDown = useCallback(\n (event: React.KeyboardEvent) => {\n // Use refs to get the latest state values to avoid stale closures\n const isShowingSuggestions = showSuggestionsRef.current;\n const currentFilteredSuggestions = filteredSuggestionsRef.current;\n const currentSelectedIndex = selectedIndexRef.current;\n\n // Always prevent Enter key to avoid creating new lines/divs\n if (event.key === 'Enter') {\n event.preventDefault();\n event.stopPropagation();\n\n // If suggestions are showing, select the current suggestion\n if (isShowingSuggestions && currentFilteredSuggestions.length > 0 && currentFilteredSuggestions[currentSelectedIndex]) {\n insertSuggestion(currentFilteredSuggestions[currentSelectedIndex]);\n }\n return;\n }\n\n // When suggestions are visible, intercept navigation keys immediately\n if (isShowingSuggestions && currentFilteredSuggestions.length > 0) {\n const { key } = event;\n\n // Prevent default for all navigation keys when suggestions are shown\n if (['ArrowDown', 'ArrowUp', 'Escape', 'Tab'].includes(key)) {\n event.preventDefault();\n event.stopPropagation();\n\n switch (key) {\n case 'ArrowDown':\n setSelectedIndex((prev) => (prev < currentFilteredSuggestions.length - 1 ? prev + 1 : prev));\n break;\n case 'ArrowUp':\n setSelectedIndex((prev) => (prev > 0 ? prev - 1 : 0));\n break;\n case 'Escape':\n setShowSuggestions(false);\n break;\n case 'Tab':\n if (currentFilteredSuggestions[currentSelectedIndex]) {\n insertSuggestion(currentFilteredSuggestions[currentSelectedIndex]);\n }\n break;\n }\n }\n }\n },\n [insertSuggestion],\n );\n\n const handlePaste = useCallback((event: React.ClipboardEvent<HTMLDivElement>) => {\n event.preventDefault();\n const text = event.clipboardData.getData('text/plain');\n document.execCommand('insertText', false, text);\n }, []);\n\n const displayValue = useMemo(() => {\n if (showRawValue) {\n return value;\n }\n return convertToPills(value);\n }, [value, showRawValue]);\n\n return (\n <div className='w-full'>\n {label && (\n <div className='text-xs font-medium text-gray-600 inline-flex items-center gap-1 font-inter text-left whitespace-nowrap flex-wrap'>\n <InputLabel label={label || \"\"} required={isRequired || false} />\n {tooltip && (\n <Tooltip placement='top' title={tooltip}>\n <div className='cursor-pointer'>\n <HelpIcon />\n </div>\n </Tooltip>\n )}\n </div>\n )}\n\n <div className='relative' ref={inputWrapperRef}>\n {!value?.trim() ? (\n <div\n className='absolute top-0 left-0 w-full h-full text-gray-400 flex items-center cursor-text px-3 z-50'\n onClick={() => contentRef.current?.focus()}\n >\n <Typography size='extra-small' variant='medium'>\n {placeholder}\n </Typography>\n </div>\n ) : null}\n\n <div className='relative'>\n <ContentEditable\n innerRef={contentRef}\n className={cn(\n 'min-h-[42px] rounded-lg p-2.5',\n 'text-sm font-inter block font-medium border text-gray-900 dark:text-white whitespace-normal break-words text-left',\n disabled ? 'bg-neutral-100 dark:bg-black-800' : 'bg-white dark:bg-black-800',\n !disabled && 'pr-[60px]',\n errorMessage ? '!border-error-500' : 'border-gray-300 dark:border-black-600 focus:ring-blue-500 focus:border-blue-500',\n 'cursor-text',\n )}\n style={{\n width: width,\n wordBreak: 'break-word',\n }}\n html={displayValue}\n onChange={!disabled ? handleChange : () => null}\n onFocus={handleFocus}\n onBlur={handleBlur}\n onKeyDownCapture={handleKeyDown}\n onKeyDown={handleKeyDown}\n onPaste={handlePaste}\n disabled={disabled}\n id={id}\n />\n\n {!disabled && (\n <div className='absolute right-0 top-0 bottom-0 flex items-center align-middle justify-center p-3 gap-2'>\n <IconButton tooltip={showRawValue ? 'Show Formatted' : 'Show Raw Value'} variant='ghost' onClick={() => setShowRawValue(!showRawValue)}>\n {showRawValue ? <VisibilityOutlined sx={{ fontSize: 18 }} /> : <VisibilityOffOutlined sx={{ fontSize: 18 }} />}\n </IconButton>\n </div>\n )}\n </div>\n\n {showSuggestions &&\n filteredSuggestions.length > 0 &&\n createPortal(\n <div\n ref={suggestionMenuRef}\n className='z-[3000] bg-white dark:bg-black-800 border border-gray-300 dark:border-black-600 rounded-lg shadow-lg max-h-60 overflow-y-auto min-w-[200px]'\n onMouseDown={(e) => {\n // Prevent blur when clicking on suggestions\n e.preventDefault();\n }}\n >\n {filteredSuggestions.map((suggestion, index) => (\n <div\n key={suggestion}\n ref={(el) => (suggestionRefs.current[index] = el)}\n className={cn(\n 'px-3 py-2 cursor-pointer text-sm font-inter',\n index === selectedIndex\n ? 'bg-primary-100 dark:bg-primary-900 text-primary-700 dark:text-primary-300'\n : 'hover:bg-gray-100 dark:hover:bg-black-700 text-gray-900 dark:text-white',\n )}\n onClick={() => insertSuggestion(suggestion)}\n onMouseEnter={() => setSelectedIndex(index)}\n >\n {suggestion}\n </div>\n ))}\n </div>,\n document.body,\n )}\n </div>\n\n {errorMessage && (\n <div className='pt-1'>\n <Typography className='text-error-500' size='extra-small' variant='medium' appearance='custom'>\n {errorMessage}\n </Typography>\n </div>\n )}\n </div>\n );\n};\n\nexport default React.memo(FormulaInput);\n\n\n\n"],"names":["FormulaInput","value","onChange","onFocus","onBlur","label","id","isRequired","tooltip","placeholder","disabled","errorMessage","width","suggestions","showRawValueProp","contentRef","useRef","inputWrapperRef","suggestionMenuRef","suggestionRefs","popperInstanceRef","showSuggestions","setShowSuggestions","useState","searchTerm","setSearchTerm","selectedIndex","setSelectedIndex","showRawValue","setShowRawValue","showSuggestionsRef","filteredSuggestionsRef","selectedIndexRef","valueRef","useEffect","useOutsideClick","filteredSuggestions","useMemo","lowerSearchTerm","suggestion","createPopper","handleChange","useCallback","event","rawValue","convertFromPills","textBeforeCursor","getTextBeforeCursor","lastAtSymbol","textAfterAt","handleFocus","handleBlur","relatedTarget","insertSuggestion","currentValue","spaceIndex","endPosition","beforeAt","afterCursor","newValue","handleKeyDown","isShowingSuggestions","currentFilteredSuggestions","currentSelectedIndex","key","prev","handlePaste","text","displayValue","convertToPills","jsxs","jsx","InputLabel","Tooltip","HelpIcon","Typography","ContentEditable","cn","IconButton","VisibilityOutlined","VisibilityOffOutlined","createPortal","index","el","FormulaInput$1","React"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"FormulaInput.es.js","sources":["../../../../src/components/forms/formula-input/FormulaInput.tsx"],"sourcesContent":["import { Instance as PopperInstance, createPopper } from '@popperjs/core';\nimport cn from 'classnames';\nimport React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport ContentEditable, { ContentEditableEvent } from 'react-contenteditable';\nimport { createPortal } from 'react-dom';\nimport { VisibilityOffOutlined, VisibilityOutlined } from '@mui/icons-material';\n\nimport { Typography } from '../../data-display/typography/Typography';\nimport IconButton from '../../button/IconButton';\nimport Tooltip from '../../tooltip/Tooltip';\nimport { HelpIcon } from '../../icons/HelpIcon';\nimport { useOutsideClick } from '../../../hooks/useOutsideClick';\nimport { convertFromPills, convertToPills, getTextBeforeCursor } from './utils';\nimport { InputLabel } from '../shared/InputLabel';\n\nexport interface FormulaInputProps {\n /** Current value of the input */\n value: string;\n /** Callback when value changes */\n onChange: (value: string) => void;\n /** Callback when input receives focus */\n onFocus?: () => void;\n /** Callback when input loses focus */\n onBlur?: () => void;\n /** Label for the input field */\n label?: string;\n /** Unique identifier for the input */\n id: string;\n /** Whether the field is required */\n required?: boolean;\n /** Tooltip text displayed next to the label */\n tooltip?: string;\n /** Placeholder text */\n placeholder?: string;\n /** Whether the input is disabled */\n disabled?: boolean;\n /** Error message to display */\n errorMessage?: string;\n /** Width of the input */\n width?: string;\n /** List of suggestions for autocomplete */\n suggestions?: string[];\n /** Whether to show the raw value instead of pills */\n showRawValue?: boolean;\n}\n\n/**\n * FormulaInput component for entering formulas with variable suggestions\n * Variables are displayed as pills and can be inserted using @ trigger\n */\nconst FormulaInput: React.FC<FormulaInputProps> = ({\n value = '',\n onChange,\n onFocus,\n onBlur,\n label,\n id,\n required: isRequired,\n tooltip,\n placeholder,\n disabled,\n errorMessage,\n width = '100%',\n suggestions = [],\n showRawValue: showRawValueProp = false,\n}) => {\n const contentRef = useRef<HTMLElement & { isFocused?: boolean }>(null);\n const inputWrapperRef = useRef<HTMLDivElement>(null);\n const suggestionMenuRef = useRef<HTMLDivElement>(null);\n const suggestionRefs = useRef<(HTMLDivElement | null)[]>([]);\n const popperInstanceRef = useRef<PopperInstance | null>(null);\n const [showSuggestions, setShowSuggestions] = useState(false);\n const [searchTerm, setSearchTerm] = useState('');\n const [selectedIndex, setSelectedIndex] = useState(0);\n const [showRawValue, setShowRawValue] = useState(showRawValueProp);\n\n // Use refs to track current state for event handlers\n const showSuggestionsRef = useRef(showSuggestions);\n const filteredSuggestionsRef = useRef<string[]>([]);\n const selectedIndexRef = useRef(selectedIndex);\n const valueRef = useRef(value);\n\n // Keep refs in sync with state\n useEffect(() => {\n showSuggestionsRef.current = showSuggestions;\n }, [showSuggestions]);\n\n useEffect(() => {\n selectedIndexRef.current = selectedIndex;\n }, [selectedIndex]);\n\n useEffect(() => {\n valueRef.current = value;\n }, [value]);\n\n // Close suggestions when clicking outside\n useOutsideClick({\n ref: suggestionMenuRef,\n handler: () => {\n if (showSuggestions) {\n setShowSuggestions(false);\n }\n },\n });\n\n // Filter suggestions based on search term\n const filteredSuggestions = useMemo(() => {\n if (!searchTerm) return suggestions;\n\n const lowerSearchTerm = searchTerm.toLowerCase();\n return suggestions.filter((suggestion) => suggestion.toLowerCase().includes(lowerSearchTerm));\n }, [suggestions, searchTerm]);\n\n // Keep filtered suggestions ref in sync\n useEffect(() => {\n filteredSuggestionsRef.current = filteredSuggestions;\n }, [filteredSuggestions]);\n\n // Reset selected index when filtered suggestions change\n useEffect(() => {\n setSelectedIndex(0);\n }, [filteredSuggestions]);\n\n // Scroll selected suggestion into view\n useEffect(() => {\n if (showSuggestions && suggestionRefs.current[selectedIndex]) {\n suggestionRefs.current[selectedIndex]?.scrollIntoView({\n block: 'nearest',\n behavior: 'smooth',\n });\n }\n }, [selectedIndex, showSuggestions]);\n\n // Setup Popper for dynamic positioning\n useEffect(() => {\n if (showSuggestions && inputWrapperRef.current && suggestionMenuRef.current) {\n // Create popper instance with auto placement\n popperInstanceRef.current = createPopper(inputWrapperRef.current, suggestionMenuRef.current, {\n placement: 'bottom-start',\n strategy: 'fixed',\n modifiers: [\n {\n name: 'flip',\n options: {\n fallbackPlacements: ['top-start', 'bottom-start'],\n },\n },\n {\n name: 'preventOverflow',\n options: {\n boundary: 'viewport',\n padding: 8,\n },\n },\n {\n name: 'offset',\n options: {\n offset: [0, 4],\n },\n },\n ],\n });\n\n return () => {\n if (popperInstanceRef.current) {\n popperInstanceRef.current.destroy();\n popperInstanceRef.current = null;\n }\n };\n }\n }, [showSuggestions]);\n\n const handleChange = useCallback(\n (event: ContentEditableEvent) => {\n const rawValue = convertFromPills(event.target.value);\n onChange(rawValue);\n\n // Check if user typed @ (trigger for suggestions)\n const textBeforeCursor = getTextBeforeCursor();\n const lastAtSymbol = textBeforeCursor.lastIndexOf('@');\n\n if (lastAtSymbol !== -1) {\n // Get text after the @ symbol\n const textAfterAt = textBeforeCursor.slice(lastAtSymbol + 1);\n\n // Check if there's a space after @, which would end the suggestion context\n const hasSpace = textAfterAt.includes(' ');\n\n if (!hasSpace) {\n // We're in suggestion mode - show suggestions filtered by text after @\n setSearchTerm(textAfterAt);\n setShowSuggestions(true);\n } else {\n setShowSuggestions(false);\n }\n } else {\n setShowSuggestions(false);\n }\n },\n [onChange],\n );\n\n const handleFocus = useCallback(() => {\n if (contentRef.current) {\n contentRef.current.isFocused = true;\n }\n onFocus?.();\n }, [onFocus]);\n\n const handleBlur = useCallback(\n (event: React.FocusEvent) => {\n if (contentRef.current) {\n contentRef.current.isFocused = false;\n }\n\n // Check if the blur is due to clicking on a suggestion\n const relatedTarget = event.relatedTarget as HTMLElement;\n if (relatedTarget && suggestionMenuRef.current?.contains(relatedTarget)) {\n // Don't close suggestions if clicking on a suggestion\n return;\n }\n\n // Delay closing suggestions to allow click events to register\n setTimeout(() => {\n setShowSuggestions(false);\n }, 200);\n onBlur?.();\n },\n [onBlur],\n );\n\n const insertSuggestion = useCallback(\n (suggestion: string) => {\n if (!contentRef.current) return;\n\n // IMPORTANT: Use the value prop (not innerText) to preserve existing {{}} syntax\n // innerText only shows display text and loses the {{}} markers from pills\n const currentValue = valueRef.current;\n\n // Find the last occurrence of @ (trigger symbol) in the raw value\n const lastAtSymbol = currentValue.lastIndexOf('@');\n\n if (lastAtSymbol !== -1) {\n // Find where the @ trigger ends (space or end of string)\n const afterAt = currentValue.slice(lastAtSymbol + 1);\n const spaceIndex = afterAt.search(/\\s/);\n\n let endPosition: number;\n if (spaceIndex === -1) {\n // No space found, the incomplete variable goes to the end\n endPosition = currentValue.length;\n } else {\n // Space found, replace up to the space\n endPosition = lastAtSymbol + 1 + spaceIndex;\n }\n\n // Build the new value preserving all existing {{}} syntax\n // Replace @searchTerm with {{suggestion}}\n const beforeAt = currentValue.slice(0, lastAtSymbol);\n const afterCursor = currentValue.slice(endPosition);\n const newValue = `${beforeAt}{{${suggestion}}}${afterCursor}`;\n\n // Update through onChange\n onChange(newValue);\n\n // Close suggestions\n setShowSuggestions(false);\n setSearchTerm('');\n\n // Refocus the input after React updates\n setTimeout(() => {\n contentRef.current?.focus();\n }, 0);\n }\n },\n [onChange],\n );\n\n const handleKeyDown = useCallback(\n (event: React.KeyboardEvent) => {\n // Use refs to get the latest state values to avoid stale closures\n const isShowingSuggestions = showSuggestionsRef.current;\n const currentFilteredSuggestions = filteredSuggestionsRef.current;\n const currentSelectedIndex = selectedIndexRef.current;\n\n // Always prevent Enter key to avoid creating new lines/divs\n if (event.key === 'Enter') {\n event.preventDefault();\n event.stopPropagation();\n\n // If suggestions are showing, select the current suggestion\n if (isShowingSuggestions && currentFilteredSuggestions.length > 0 && currentFilteredSuggestions[currentSelectedIndex]) {\n insertSuggestion(currentFilteredSuggestions[currentSelectedIndex]);\n }\n return;\n }\n\n // When suggestions are visible, intercept navigation keys immediately\n if (isShowingSuggestions && currentFilteredSuggestions.length > 0) {\n const { key } = event;\n\n // Prevent default for all navigation keys when suggestions are shown\n if (['ArrowDown', 'ArrowUp', 'Escape', 'Tab'].includes(key)) {\n event.preventDefault();\n event.stopPropagation();\n\n switch (key) {\n case 'ArrowDown':\n setSelectedIndex((prev) => (prev < currentFilteredSuggestions.length - 1 ? prev + 1 : prev));\n break;\n case 'ArrowUp':\n setSelectedIndex((prev) => (prev > 0 ? prev - 1 : 0));\n break;\n case 'Escape':\n setShowSuggestions(false);\n break;\n case 'Tab':\n if (currentFilteredSuggestions[currentSelectedIndex]) {\n insertSuggestion(currentFilteredSuggestions[currentSelectedIndex]);\n }\n break;\n }\n }\n }\n },\n [insertSuggestion],\n );\n\n const handlePaste = useCallback((event: React.ClipboardEvent<HTMLDivElement>) => {\n event.preventDefault();\n const text = event.clipboardData.getData('text/plain');\n document.execCommand('insertText', false, text);\n }, []);\n\n const displayValue = useMemo(() => {\n if (showRawValue) {\n return value;\n }\n return convertToPills(value);\n }, [value, showRawValue]);\n\n return (\n <div className='w-full'>\n {label && (\n <div className='text-xs font-medium text-gray-600 inline-flex items-center gap-1 font-inter text-left whitespace-nowrap flex-wrap'>\n <InputLabel label={label || \"\"} required={isRequired || false} />\n {tooltip && (\n <Tooltip placement='top' title={tooltip}>\n <div className='cursor-pointer'>\n <HelpIcon className=\"w-icon-sm h-icon-sm\" />\n </div>\n </Tooltip>\n )}\n </div>\n )}\n\n <div className='relative' ref={inputWrapperRef}>\n {!value?.trim() ? (\n <div\n className='absolute top-0 left-0 w-full h-full text-gray-400 flex items-center cursor-text px-3 z-50'\n onClick={() => contentRef.current?.focus()}\n >\n <Typography size='extra-small' variant='medium'>\n {placeholder}\n </Typography>\n </div>\n ) : null}\n\n <div className='relative'>\n <ContentEditable\n innerRef={contentRef}\n className={cn(\n 'min-h-[42px] rounded-lg p-2.5',\n 'text-sm font-inter block font-medium border text-gray-900 dark:text-white whitespace-normal break-words text-left',\n disabled ? 'bg-neutral-100 dark:bg-black-800' : 'bg-white dark:bg-black-800',\n !disabled && 'pr-[60px]',\n errorMessage ? '!border-error-500' : 'border-gray-300 dark:border-black-600 focus:ring-blue-500 focus:border-blue-500',\n 'cursor-text',\n )}\n style={{\n width: width,\n wordBreak: 'break-word',\n }}\n html={displayValue}\n onChange={!disabled ? handleChange : () => null}\n onFocus={handleFocus}\n onBlur={handleBlur}\n onKeyDownCapture={handleKeyDown}\n onKeyDown={handleKeyDown}\n onPaste={handlePaste}\n disabled={disabled}\n id={id}\n />\n\n {!disabled && (\n <div className='absolute right-0 top-0 bottom-0 flex items-center align-middle justify-center p-3 gap-2'>\n <IconButton tooltip={showRawValue ? 'Show Formatted' : 'Show Raw Value'} variant='ghost' onClick={() => setShowRawValue(!showRawValue)}>\n {showRawValue ? <VisibilityOutlined sx={{ fontSize: 18 }} /> : <VisibilityOffOutlined sx={{ fontSize: 18 }} />}\n </IconButton>\n </div>\n )}\n </div>\n\n {showSuggestions &&\n filteredSuggestions.length > 0 &&\n createPortal(\n <div\n ref={suggestionMenuRef}\n className='z-[3000] bg-white dark:bg-black-800 border border-gray-300 dark:border-black-600 rounded-lg shadow-lg max-h-60 overflow-y-auto min-w-[200px]'\n onMouseDown={(e) => {\n // Prevent blur when clicking on suggestions\n e.preventDefault();\n }}\n >\n {filteredSuggestions.map((suggestion, index) => (\n <div\n key={suggestion}\n ref={(el) => (suggestionRefs.current[index] = el)}\n className={cn(\n 'px-3 py-2 cursor-pointer text-sm font-inter',\n index === selectedIndex\n ? 'bg-primary-100 dark:bg-primary-900 text-primary-700 dark:text-primary-300'\n : 'hover:bg-gray-100 dark:hover:bg-black-700 text-gray-900 dark:text-white',\n )}\n onClick={() => insertSuggestion(suggestion)}\n onMouseEnter={() => setSelectedIndex(index)}\n >\n {suggestion}\n </div>\n ))}\n </div>,\n document.body,\n )}\n </div>\n\n {errorMessage && (\n <div className='pt-1'>\n <Typography className='text-error-500' size='extra-small' variant='medium' appearance='custom'>\n {errorMessage}\n </Typography>\n </div>\n )}\n </div>\n );\n};\n\nexport default React.memo(FormulaInput);\n\n\n\n"],"names":["FormulaInput","value","onChange","onFocus","onBlur","label","id","isRequired","tooltip","placeholder","disabled","errorMessage","width","suggestions","showRawValueProp","contentRef","useRef","inputWrapperRef","suggestionMenuRef","suggestionRefs","popperInstanceRef","showSuggestions","setShowSuggestions","useState","searchTerm","setSearchTerm","selectedIndex","setSelectedIndex","showRawValue","setShowRawValue","showSuggestionsRef","filteredSuggestionsRef","selectedIndexRef","valueRef","useEffect","useOutsideClick","filteredSuggestions","useMemo","lowerSearchTerm","suggestion","createPopper","handleChange","useCallback","event","rawValue","convertFromPills","textBeforeCursor","getTextBeforeCursor","lastAtSymbol","textAfterAt","handleFocus","handleBlur","relatedTarget","insertSuggestion","currentValue","spaceIndex","endPosition","beforeAt","afterCursor","newValue","handleKeyDown","isShowingSuggestions","currentFilteredSuggestions","currentSelectedIndex","key","prev","handlePaste","text","displayValue","convertToPills","jsxs","jsx","InputLabel","Tooltip","HelpIcon","Typography","ContentEditable","cn","IconButton","VisibilityOutlined","VisibilityOffOutlined","createPortal","index","el","FormulaInput$1","React"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InputField.cjs.js","sources":["../../../../src/components/forms/input-field/InputField.tsx"],"sourcesContent":["import cn from \"classnames\";\nimport { AnimatePresence, motion } from \"framer-motion\";\nimport React, { forwardRef, useEffect, useRef, useState } from \"react\";\nimport { Typography } from \"../../data-display/typography/Typography\";\nimport { InputLabel } from \"../shared/InputLabel\";\n\n/**\n * Props for the InputField component\n */\nexport interface InputFieldProps {\n /** Unique identifier for the input field */\n id: string;\n /** The current value of the input field */\n value?: string;\n /** Callback function called when the input value changes */\n onChange: (value: string) => void;\n /** Callback function called on key down events */\n onKeyDown?: (event: React.KeyboardEvent<HTMLInputElement>) => void;\n /** Error message to display below the input */\n message?: string;\n /** Success message to display below the input */\n messageType?: \"success\" | \"error\" | \"info\" | \"default\";\n /** Default value for the input field */\n defaultValue?: string;\n /** Whether the input field is disabled */\n disabled?: boolean;\n /** Maximum value for number inputs */\n max?: number;\n /** Minimum value for number inputs */\n min?: number;\n /** Whether the field is required */\n required?: boolean;\n /** Label text for the input field */\n label?: string;\n /** Input type (text, email, password, number, etc.) */\n type?: string;\n /** Placeholder text for the input */\n placeholder?: string;\n /** Icon or element to display at the end of the input */\n fieldSuffix?: React.ReactNode;\n /** Additional CSS classes for the wrapper container */\n wrapperClassNames?: string;\n /** Additional CSS classes for the input element */\n inputClassNames?: string;\n /** Inline styles for the input element */\n inputStyle?: React.CSSProperties;\n /** Additional props to pass to the input element */\n inputProps?: React.InputHTMLAttributes<HTMLInputElement>;\n}\n/**\n * A highly customizable input field component with label, validation, and styling support.\n *\n * @example\n * ```tsx\n * <InputField\n * id=\"email\"\n * label=\"Email Address\"\n * type=\"email\"\n * value={email}\n * onChange={setEmail}\n * placeholder=\"Enter your email\"\n * required\n * errorMessage={emailError}\n * />\n * ```\n */\nexport const InputField = forwardRef<HTMLInputElement, InputFieldProps>(\n (\n {\n id,\n value,\n onChange,\n onKeyDown,\n message,\n messageType = \"default\",\n defaultValue,\n disabled = false,\n max,\n min,\n required = false,\n label,\n type = \"text\",\n placeholder,\n fieldSuffix,\n wrapperClassNames,\n inputClassNames,\n inputStyle = {},\n inputProps,\n },\n ref\n ) => {\n // Refs and state for dynamic padding\n const suffixRef = useRef<HTMLDivElement>(null);\n const [suffixWidth, setSuffixWidth] = useState<number>(0);\n\n // Base styles for different states\n const getInputBorderClasses = (): string => {\n if (messageType === \"error\")\n return \"border-red-300 focus:border-red-500 focus:ring-red-200\";\n if (messageType === \"success\")\n return \"border-green-300 focus:border-green-500 focus:ring-green-200\";\n if (messageType === \"info\")\n return \"border-blue-300 focus:border-blue-500 focus:ring-blue-200\";\n return \"border-neutral-200 dark:border-black-600 focus:border-primary-500 dark:focus:border-primary-400 focus:ring-primary-200 dark:focus:ring-primary-400/20\";\n };\n\n // Typography class for message\n const getMessageTypographyClass = (): string => {\n if (messageType === \"error\") return \"text-red-500 dark:text-red-400\";\n if (messageType === \"success\")\n return \"text-green-500 dark:text-green-400\";\n if (messageType === \"info\") return \"text-blue-500 dark:text-blue-400\";\n return \"text-neutral-500 dark:text-black-100\";\n };\n\n const inputId = id || `input-${label?.replace(/\\s+/g, \"-\").toLowerCase()}`;\n\n // Effect to measure suffix width and update input padding\n useEffect(() => {\n if (fieldSuffix && suffixRef.current) {\n const resizeObserver = new ResizeObserver((entries) => {\n const suffixElement = entries[0];\n if (suffixElement) {\n // Add extra padding (8px base + 4px buffer) to prevent overlap\n const calculatedWidth =\n Math.ceil(suffixElement.contentRect.width) + 24;\n setSuffixWidth(calculatedWidth);\n }\n });\n\n resizeObserver.observe(suffixRef.current);\n\n // Initial measurement\n const initialWidth = Math.ceil(suffixRef.current.offsetWidth) + 12;\n setSuffixWidth(initialWidth);\n\n return () => {\n resizeObserver.disconnect();\n };\n } else {\n setSuffixWidth(0);\n }\n }, [fieldSuffix]);\n\n // Calculate dynamic padding style\n const getDynamicInputStyle = (): React.CSSProperties => {\n const basePadding = 12; // Default px-3 is 12px\n const rightPadding = fieldSuffix\n ? Math.max(basePadding, suffixWidth)\n : basePadding;\n\n return {\n \"--input-bg-color\": \"var(--tw-bg-opacity, 1) rgb(var(--bg-color))\",\n \"--text-color\": \"#111827\",\n paddingRight: `${rightPadding}px`,\n ...inputStyle,\n } as React.CSSProperties;\n };\n\n return (\n <div className={cn(\"flex flex-col w-full\", wrapperClassNames)}>\n {/* Autofill styles */}\n <style>\n {`\n .input-field input:-webkit-autofill,\n .input-field input:-webkit-autofill:hover,\n .input-field input:-webkit-autofill:focus {\n -webkit-text-fill-color: var(--text-color) !important;\n -webkit-box-shadow: 0 0 0px 1000px var(--input-bg-color) inset !important;\n transition: background-color 5000s ease-in-out 0s;\n }\n \n .dark .input-field input:-webkit-autofill,\n .dark .input-field input:-webkit-autofill:hover,\n .dark .input-field input:-webkit-autofill:focus {\n -webkit-text-fill-color: white !important;\n -webkit-box-shadow: 0 0 0px 1000px var(--input-bg-color) inset !important;\n }\n `}\n </style>\n\n {/* Label */}\n {label ? (\n <label\n htmlFor={inputId}\n className=\"mb-1 text-xs font-medium text-gray-600 dark:text-gray-300 inline-flex items-center gap-1\"\n >\n <div className=\"flex flex-wrap items-center justify-between w-full\">\n <div className=\"inline-flex flex-wrap items-center gap-1\">\n <InputLabel label={label || \"\"} required={required || false} />\n {/* TODO: Add tooltip support when Tooltip component is available */}\n {/* {tooltip && (\n <Tooltip placement=\"top\" title={tooltip}>\n <div className=\"cursor-pointer\">\n <HelpIcon className=\"text-neutral-500 w-3 h-3\" />\n </div>\n </Tooltip>\n )} */}\n </div>\n </div>\n </label>\n ) : null}\n\n {/* Input Container */}\n <div className=\"relative input-field\">\n <input\n {...inputProps}\n ref={ref}\n id={inputId}\n type={type}\n value={value}\n defaultValue={defaultValue}\n placeholder={placeholder}\n required={required}\n disabled={disabled}\n max={max}\n min={min}\n onKeyDown={onKeyDown}\n style={getDynamicInputStyle()}\n className={cn(\n // Base styles\n \"border border-solid h-8 rounded-md block w-full pl-3\",\n \"text-sm font-medium text-neutral-900 dark:text-black-100\",\n \"bg-white dark:bg-black-600\",\n \"transition-colors duration-200 ease-in-out\",\n \"focus:outline-none focus:ring-2\",\n\n // State-specific styles\n getInputBorderClasses(),\n\n // Disabled styles\n disabled &&\n \"opacity-70 cursor-not-allowed bg-neutral-50 dark:bg-black-700\",\n\n // Custom classes\n inputClassNames\n )}\n onChange={(e) => onChange(e.target.value)}\n onClick={(e) => e.stopPropagation()}\n />\n\n {/* Suffix Icon */}\n {fieldSuffix && (\n <div\n ref={suffixRef}\n className=\"absolute inset-y-0 right-0 pr-3 flex items-center pointer-events-none\"\n >\n {fieldSuffix}\n </div>\n )}\n </div>\n\n {/* Error Message */}\n <AnimatePresence>\n {message && (\n <motion.div\n initial={{ opacity: 0, y: -10 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: -10 }}\n transition={{ duration: 0.2 }}\n >\n <Typography\n className={cn(\"mt-1\", getMessageTypographyClass())}\n appearance=\"custom\"\n size=\"extra-small\"\n variant=\"medium\"\n >\n {message}\n </Typography>\n </motion.div>\n )}\n </AnimatePresence>\n </div>\n );\n }\n);\n\nInputField.displayName = \"InputField\";\n"],"names":["InputField","forwardRef","id","value","onChange","onKeyDown","message","messageType","defaultValue","disabled","max","min","required","label","type","placeholder","fieldSuffix","wrapperClassNames","inputClassNames","inputStyle","inputProps","ref","suffixRef","useRef","suffixWidth","setSuffixWidth","useState","getInputBorderClasses","getMessageTypographyClass","inputId","useEffect","resizeObserver","entries","suffixElement","calculatedWidth","initialWidth","getDynamicInputStyle","cn","jsx","InputLabel","jsxs","e","AnimatePresence","motion","Typography"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"InputField.cjs.js","sources":["../../../../src/components/forms/input-field/InputField.tsx"],"sourcesContent":["import cn from \"classnames\";\nimport { AnimatePresence, motion } from \"framer-motion\";\nimport React, { forwardRef, useEffect, useRef, useState } from \"react\";\nimport { Typography } from \"../../data-display/typography/Typography\";\nimport { InputLabel } from \"../shared/InputLabel\";\n\n/**\n * Props for the InputField component\n */\nexport interface InputFieldProps {\n /** Unique identifier for the input field */\n id: string;\n /** The current value of the input field */\n value?: string;\n /** Callback function called when the input value changes */\n onChange: (value: string) => void;\n /** Callback function called on key down events */\n onKeyDown?: (event: React.KeyboardEvent<HTMLInputElement>) => void;\n /** Error message to display below the input */\n message?: string;\n /** Success message to display below the input */\n messageType?: \"success\" | \"error\" | \"info\" | \"default\";\n /** Default value for the input field */\n defaultValue?: string;\n /** Whether the input field is disabled */\n disabled?: boolean;\n /** Maximum value for number inputs */\n max?: number;\n /** Minimum value for number inputs */\n min?: number;\n /** Whether the field is required */\n required?: boolean;\n /** Label text for the input field */\n label?: string;\n /** Input type (text, email, password, number, etc.) */\n type?: string;\n /** Placeholder text for the input */\n placeholder?: string;\n /** Icon or element to display at the end of the input */\n fieldSuffix?: React.ReactNode;\n /** Additional CSS classes for the wrapper container */\n wrapperClassNames?: string;\n /** Additional CSS classes for the input element */\n inputClassNames?: string;\n /** Inline styles for the input element */\n inputStyle?: React.CSSProperties;\n /** Additional props to pass to the input element */\n inputProps?: React.InputHTMLAttributes<HTMLInputElement>;\n}\n/**\n * A highly customizable input field component with label, validation, and styling support.\n *\n * @example\n * ```tsx\n * <InputField\n * id=\"email\"\n * label=\"Email Address\"\n * type=\"email\"\n * value={email}\n * onChange={setEmail}\n * placeholder=\"Enter your email\"\n * required\n * errorMessage={emailError}\n * />\n * ```\n */\nexport const InputField = forwardRef<HTMLInputElement, InputFieldProps>(\n (\n {\n id,\n value,\n onChange,\n onKeyDown,\n message,\n messageType = \"default\",\n defaultValue,\n disabled = false,\n max,\n min,\n required = false,\n label,\n type = \"text\",\n placeholder,\n fieldSuffix,\n wrapperClassNames,\n inputClassNames,\n inputStyle = {},\n inputProps,\n },\n ref\n ) => {\n // Refs and state for dynamic padding\n const suffixRef = useRef<HTMLDivElement>(null);\n const [suffixWidth, setSuffixWidth] = useState<number>(0);\n\n // Base styles for different states\n const getInputBorderClasses = (): string => {\n if (messageType === \"error\")\n return \"border-red-300 focus:border-red-500 focus:ring-red-200\";\n if (messageType === \"success\")\n return \"border-green-300 focus:border-green-500 focus:ring-green-200\";\n if (messageType === \"info\")\n return \"border-blue-300 focus:border-blue-500 focus:ring-blue-200\";\n return \"border-neutral-200 dark:border-black-600 focus:border-primary-500 dark:focus:border-primary-400 focus:ring-primary-200 dark:focus:ring-primary-400/20\";\n };\n\n // Typography class for message\n const getMessageTypographyClass = (): string => {\n if (messageType === \"error\") return \"text-red-500 dark:text-red-400\";\n if (messageType === \"success\")\n return \"text-green-500 dark:text-green-400\";\n if (messageType === \"info\") return \"text-blue-500 dark:text-blue-400\";\n return \"text-neutral-500 dark:text-black-100\";\n };\n\n const inputId = id || `input-${label?.replace(/\\s+/g, \"-\").toLowerCase()}`;\n\n // Effect to measure suffix width and update input padding\n useEffect(() => {\n if (fieldSuffix && suffixRef.current) {\n const resizeObserver = new ResizeObserver((entries) => {\n const suffixElement = entries[0];\n if (suffixElement) {\n // Add extra padding (8px base + 4px buffer) to prevent overlap\n const calculatedWidth =\n Math.ceil(suffixElement.contentRect.width) + 24;\n setSuffixWidth(calculatedWidth);\n }\n });\n\n resizeObserver.observe(suffixRef.current);\n\n // Initial measurement\n const initialWidth = Math.ceil(suffixRef.current.offsetWidth) + 12;\n setSuffixWidth(initialWidth);\n\n return () => {\n resizeObserver.disconnect();\n };\n } else {\n setSuffixWidth(0);\n }\n }, [fieldSuffix]);\n\n // Calculate dynamic padding style\n const getDynamicInputStyle = (): React.CSSProperties => {\n const basePadding = 12; // Default px-3 is 12px\n const rightPadding = fieldSuffix\n ? Math.max(basePadding, suffixWidth)\n : basePadding;\n\n return {\n \"--input-bg-color\": \"var(--tw-bg-opacity, 1) rgb(var(--bg-color))\",\n \"--text-color\": \"#111827\",\n paddingRight: `${rightPadding}px`,\n ...inputStyle,\n } as React.CSSProperties;\n };\n\n return (\n <div className={cn(\"flex flex-col w-full\", wrapperClassNames)}>\n {/* Autofill styles */}\n <style>\n {`\n .input-field input:-webkit-autofill,\n .input-field input:-webkit-autofill:hover,\n .input-field input:-webkit-autofill:focus {\n -webkit-text-fill-color: var(--text-color) !important;\n -webkit-box-shadow: 0 0 0px 1000px var(--input-bg-color) inset !important;\n transition: background-color 5000s ease-in-out 0s;\n }\n \n .dark .input-field input:-webkit-autofill,\n .dark .input-field input:-webkit-autofill:hover,\n .dark .input-field input:-webkit-autofill:focus {\n -webkit-text-fill-color: white !important;\n -webkit-box-shadow: 0 0 0px 1000px var(--input-bg-color) inset !important;\n }\n `}\n </style>\n\n {/* Label */}\n {label ? (\n <label\n htmlFor={inputId}\n className=\"mb-1 text-xs font-medium text-gray-600 dark:text-gray-300 inline-flex items-center gap-1\"\n >\n <div className=\"flex flex-wrap items-center justify-between w-full\">\n <div className=\"inline-flex flex-wrap items-center gap-1\">\n <InputLabel label={label || \"\"} required={required || false} />\n {/* TODO: Add tooltip support when Tooltip component is available */}\n {/* {tooltip && (\n <Tooltip placement=\"top\" title={tooltip}>\n <div className=\"cursor-pointer\">\n <HelpIcon className=\"w-icon-sm h-icon-sm\" />\n </div>\n </Tooltip>\n )} */}\n </div>\n </div>\n </label>\n ) : null}\n\n {/* Input Container */}\n <div className=\"relative input-field\">\n <input\n {...inputProps}\n ref={ref}\n id={inputId}\n type={type}\n value={value}\n defaultValue={defaultValue}\n placeholder={placeholder}\n required={required}\n disabled={disabled}\n max={max}\n min={min}\n onKeyDown={onKeyDown}\n style={getDynamicInputStyle()}\n className={cn(\n // Base styles\n \"border border-solid h-8 rounded-md block w-full pl-3\",\n \"text-sm font-medium text-neutral-900 dark:text-black-100\",\n \"bg-white dark:bg-black-600\",\n \"transition-colors duration-200 ease-in-out\",\n \"focus:outline-none focus:ring-2\",\n\n // State-specific styles\n getInputBorderClasses(),\n\n // Disabled styles\n disabled &&\n \"opacity-70 cursor-not-allowed bg-neutral-50 dark:bg-black-700\",\n\n // Custom classes\n inputClassNames\n )}\n onChange={(e) => onChange(e.target.value)}\n onClick={(e) => e.stopPropagation()}\n />\n\n {/* Suffix Icon */}\n {fieldSuffix && (\n <div\n ref={suffixRef}\n className=\"absolute inset-y-0 right-0 pr-3 flex items-center pointer-events-none\"\n >\n {fieldSuffix}\n </div>\n )}\n </div>\n\n {/* Error Message */}\n <AnimatePresence>\n {message && (\n <motion.div\n initial={{ opacity: 0, y: -10 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: -10 }}\n transition={{ duration: 0.2 }}\n >\n <Typography\n className={cn(\"mt-1\", getMessageTypographyClass())}\n appearance=\"custom\"\n size=\"extra-small\"\n variant=\"medium\"\n >\n {message}\n </Typography>\n </motion.div>\n )}\n </AnimatePresence>\n </div>\n );\n }\n);\n\nInputField.displayName = \"InputField\";\n"],"names":["InputField","forwardRef","id","value","onChange","onKeyDown","message","messageType","defaultValue","disabled","max","min","required","label","type","placeholder","fieldSuffix","wrapperClassNames","inputClassNames","inputStyle","inputProps","ref","suffixRef","useRef","suffixWidth","setSuffixWidth","useState","getInputBorderClasses","getMessageTypographyClass","inputId","useEffect","resizeObserver","entries","suffixElement","calculatedWidth","initialWidth","getDynamicInputStyle","cn","jsx","InputLabel","jsxs","e","AnimatePresence","motion","Typography"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InputField.es.js","sources":["../../../../src/components/forms/input-field/InputField.tsx"],"sourcesContent":["import cn from \"classnames\";\nimport { AnimatePresence, motion } from \"framer-motion\";\nimport React, { forwardRef, useEffect, useRef, useState } from \"react\";\nimport { Typography } from \"../../data-display/typography/Typography\";\nimport { InputLabel } from \"../shared/InputLabel\";\n\n/**\n * Props for the InputField component\n */\nexport interface InputFieldProps {\n /** Unique identifier for the input field */\n id: string;\n /** The current value of the input field */\n value?: string;\n /** Callback function called when the input value changes */\n onChange: (value: string) => void;\n /** Callback function called on key down events */\n onKeyDown?: (event: React.KeyboardEvent<HTMLInputElement>) => void;\n /** Error message to display below the input */\n message?: string;\n /** Success message to display below the input */\n messageType?: \"success\" | \"error\" | \"info\" | \"default\";\n /** Default value for the input field */\n defaultValue?: string;\n /** Whether the input field is disabled */\n disabled?: boolean;\n /** Maximum value for number inputs */\n max?: number;\n /** Minimum value for number inputs */\n min?: number;\n /** Whether the field is required */\n required?: boolean;\n /** Label text for the input field */\n label?: string;\n /** Input type (text, email, password, number, etc.) */\n type?: string;\n /** Placeholder text for the input */\n placeholder?: string;\n /** Icon or element to display at the end of the input */\n fieldSuffix?: React.ReactNode;\n /** Additional CSS classes for the wrapper container */\n wrapperClassNames?: string;\n /** Additional CSS classes for the input element */\n inputClassNames?: string;\n /** Inline styles for the input element */\n inputStyle?: React.CSSProperties;\n /** Additional props to pass to the input element */\n inputProps?: React.InputHTMLAttributes<HTMLInputElement>;\n}\n/**\n * A highly customizable input field component with label, validation, and styling support.\n *\n * @example\n * ```tsx\n * <InputField\n * id=\"email\"\n * label=\"Email Address\"\n * type=\"email\"\n * value={email}\n * onChange={setEmail}\n * placeholder=\"Enter your email\"\n * required\n * errorMessage={emailError}\n * />\n * ```\n */\nexport const InputField = forwardRef<HTMLInputElement, InputFieldProps>(\n (\n {\n id,\n value,\n onChange,\n onKeyDown,\n message,\n messageType = \"default\",\n defaultValue,\n disabled = false,\n max,\n min,\n required = false,\n label,\n type = \"text\",\n placeholder,\n fieldSuffix,\n wrapperClassNames,\n inputClassNames,\n inputStyle = {},\n inputProps,\n },\n ref\n ) => {\n // Refs and state for dynamic padding\n const suffixRef = useRef<HTMLDivElement>(null);\n const [suffixWidth, setSuffixWidth] = useState<number>(0);\n\n // Base styles for different states\n const getInputBorderClasses = (): string => {\n if (messageType === \"error\")\n return \"border-red-300 focus:border-red-500 focus:ring-red-200\";\n if (messageType === \"success\")\n return \"border-green-300 focus:border-green-500 focus:ring-green-200\";\n if (messageType === \"info\")\n return \"border-blue-300 focus:border-blue-500 focus:ring-blue-200\";\n return \"border-neutral-200 dark:border-black-600 focus:border-primary-500 dark:focus:border-primary-400 focus:ring-primary-200 dark:focus:ring-primary-400/20\";\n };\n\n // Typography class for message\n const getMessageTypographyClass = (): string => {\n if (messageType === \"error\") return \"text-red-500 dark:text-red-400\";\n if (messageType === \"success\")\n return \"text-green-500 dark:text-green-400\";\n if (messageType === \"info\") return \"text-blue-500 dark:text-blue-400\";\n return \"text-neutral-500 dark:text-black-100\";\n };\n\n const inputId = id || `input-${label?.replace(/\\s+/g, \"-\").toLowerCase()}`;\n\n // Effect to measure suffix width and update input padding\n useEffect(() => {\n if (fieldSuffix && suffixRef.current) {\n const resizeObserver = new ResizeObserver((entries) => {\n const suffixElement = entries[0];\n if (suffixElement) {\n // Add extra padding (8px base + 4px buffer) to prevent overlap\n const calculatedWidth =\n Math.ceil(suffixElement.contentRect.width) + 24;\n setSuffixWidth(calculatedWidth);\n }\n });\n\n resizeObserver.observe(suffixRef.current);\n\n // Initial measurement\n const initialWidth = Math.ceil(suffixRef.current.offsetWidth) + 12;\n setSuffixWidth(initialWidth);\n\n return () => {\n resizeObserver.disconnect();\n };\n } else {\n setSuffixWidth(0);\n }\n }, [fieldSuffix]);\n\n // Calculate dynamic padding style\n const getDynamicInputStyle = (): React.CSSProperties => {\n const basePadding = 12; // Default px-3 is 12px\n const rightPadding = fieldSuffix\n ? Math.max(basePadding, suffixWidth)\n : basePadding;\n\n return {\n \"--input-bg-color\": \"var(--tw-bg-opacity, 1) rgb(var(--bg-color))\",\n \"--text-color\": \"#111827\",\n paddingRight: `${rightPadding}px`,\n ...inputStyle,\n } as React.CSSProperties;\n };\n\n return (\n <div className={cn(\"flex flex-col w-full\", wrapperClassNames)}>\n {/* Autofill styles */}\n <style>\n {`\n .input-field input:-webkit-autofill,\n .input-field input:-webkit-autofill:hover,\n .input-field input:-webkit-autofill:focus {\n -webkit-text-fill-color: var(--text-color) !important;\n -webkit-box-shadow: 0 0 0px 1000px var(--input-bg-color) inset !important;\n transition: background-color 5000s ease-in-out 0s;\n }\n \n .dark .input-field input:-webkit-autofill,\n .dark .input-field input:-webkit-autofill:hover,\n .dark .input-field input:-webkit-autofill:focus {\n -webkit-text-fill-color: white !important;\n -webkit-box-shadow: 0 0 0px 1000px var(--input-bg-color) inset !important;\n }\n `}\n </style>\n\n {/* Label */}\n {label ? (\n <label\n htmlFor={inputId}\n className=\"mb-1 text-xs font-medium text-gray-600 dark:text-gray-300 inline-flex items-center gap-1\"\n >\n <div className=\"flex flex-wrap items-center justify-between w-full\">\n <div className=\"inline-flex flex-wrap items-center gap-1\">\n <InputLabel label={label || \"\"} required={required || false} />\n {/* TODO: Add tooltip support when Tooltip component is available */}\n {/* {tooltip && (\n <Tooltip placement=\"top\" title={tooltip}>\n <div className=\"cursor-pointer\">\n <HelpIcon className=\"text-neutral-500 w-3 h-3\" />\n </div>\n </Tooltip>\n )} */}\n </div>\n </div>\n </label>\n ) : null}\n\n {/* Input Container */}\n <div className=\"relative input-field\">\n <input\n {...inputProps}\n ref={ref}\n id={inputId}\n type={type}\n value={value}\n defaultValue={defaultValue}\n placeholder={placeholder}\n required={required}\n disabled={disabled}\n max={max}\n min={min}\n onKeyDown={onKeyDown}\n style={getDynamicInputStyle()}\n className={cn(\n // Base styles\n \"border border-solid h-8 rounded-md block w-full pl-3\",\n \"text-sm font-medium text-neutral-900 dark:text-black-100\",\n \"bg-white dark:bg-black-600\",\n \"transition-colors duration-200 ease-in-out\",\n \"focus:outline-none focus:ring-2\",\n\n // State-specific styles\n getInputBorderClasses(),\n\n // Disabled styles\n disabled &&\n \"opacity-70 cursor-not-allowed bg-neutral-50 dark:bg-black-700\",\n\n // Custom classes\n inputClassNames\n )}\n onChange={(e) => onChange(e.target.value)}\n onClick={(e) => e.stopPropagation()}\n />\n\n {/* Suffix Icon */}\n {fieldSuffix && (\n <div\n ref={suffixRef}\n className=\"absolute inset-y-0 right-0 pr-3 flex items-center pointer-events-none\"\n >\n {fieldSuffix}\n </div>\n )}\n </div>\n\n {/* Error Message */}\n <AnimatePresence>\n {message && (\n <motion.div\n initial={{ opacity: 0, y: -10 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: -10 }}\n transition={{ duration: 0.2 }}\n >\n <Typography\n className={cn(\"mt-1\", getMessageTypographyClass())}\n appearance=\"custom\"\n size=\"extra-small\"\n variant=\"medium\"\n >\n {message}\n </Typography>\n </motion.div>\n )}\n </AnimatePresence>\n </div>\n );\n }\n);\n\nInputField.displayName = \"InputField\";\n"],"names":["InputField","forwardRef","id","value","onChange","onKeyDown","message","messageType","defaultValue","disabled","max","min","required","label","type","placeholder","fieldSuffix","wrapperClassNames","inputClassNames","inputStyle","inputProps","ref","suffixRef","useRef","suffixWidth","setSuffixWidth","useState","getInputBorderClasses","getMessageTypographyClass","inputId","useEffect","resizeObserver","entries","suffixElement","calculatedWidth","initialWidth","getDynamicInputStyle","cn","jsx","InputLabel","jsxs","AnimatePresence","motion","Typography"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"InputField.es.js","sources":["../../../../src/components/forms/input-field/InputField.tsx"],"sourcesContent":["import cn from \"classnames\";\nimport { AnimatePresence, motion } from \"framer-motion\";\nimport React, { forwardRef, useEffect, useRef, useState } from \"react\";\nimport { Typography } from \"../../data-display/typography/Typography\";\nimport { InputLabel } from \"../shared/InputLabel\";\n\n/**\n * Props for the InputField component\n */\nexport interface InputFieldProps {\n /** Unique identifier for the input field */\n id: string;\n /** The current value of the input field */\n value?: string;\n /** Callback function called when the input value changes */\n onChange: (value: string) => void;\n /** Callback function called on key down events */\n onKeyDown?: (event: React.KeyboardEvent<HTMLInputElement>) => void;\n /** Error message to display below the input */\n message?: string;\n /** Success message to display below the input */\n messageType?: \"success\" | \"error\" | \"info\" | \"default\";\n /** Default value for the input field */\n defaultValue?: string;\n /** Whether the input field is disabled */\n disabled?: boolean;\n /** Maximum value for number inputs */\n max?: number;\n /** Minimum value for number inputs */\n min?: number;\n /** Whether the field is required */\n required?: boolean;\n /** Label text for the input field */\n label?: string;\n /** Input type (text, email, password, number, etc.) */\n type?: string;\n /** Placeholder text for the input */\n placeholder?: string;\n /** Icon or element to display at the end of the input */\n fieldSuffix?: React.ReactNode;\n /** Additional CSS classes for the wrapper container */\n wrapperClassNames?: string;\n /** Additional CSS classes for the input element */\n inputClassNames?: string;\n /** Inline styles for the input element */\n inputStyle?: React.CSSProperties;\n /** Additional props to pass to the input element */\n inputProps?: React.InputHTMLAttributes<HTMLInputElement>;\n}\n/**\n * A highly customizable input field component with label, validation, and styling support.\n *\n * @example\n * ```tsx\n * <InputField\n * id=\"email\"\n * label=\"Email Address\"\n * type=\"email\"\n * value={email}\n * onChange={setEmail}\n * placeholder=\"Enter your email\"\n * required\n * errorMessage={emailError}\n * />\n * ```\n */\nexport const InputField = forwardRef<HTMLInputElement, InputFieldProps>(\n (\n {\n id,\n value,\n onChange,\n onKeyDown,\n message,\n messageType = \"default\",\n defaultValue,\n disabled = false,\n max,\n min,\n required = false,\n label,\n type = \"text\",\n placeholder,\n fieldSuffix,\n wrapperClassNames,\n inputClassNames,\n inputStyle = {},\n inputProps,\n },\n ref\n ) => {\n // Refs and state for dynamic padding\n const suffixRef = useRef<HTMLDivElement>(null);\n const [suffixWidth, setSuffixWidth] = useState<number>(0);\n\n // Base styles for different states\n const getInputBorderClasses = (): string => {\n if (messageType === \"error\")\n return \"border-red-300 focus:border-red-500 focus:ring-red-200\";\n if (messageType === \"success\")\n return \"border-green-300 focus:border-green-500 focus:ring-green-200\";\n if (messageType === \"info\")\n return \"border-blue-300 focus:border-blue-500 focus:ring-blue-200\";\n return \"border-neutral-200 dark:border-black-600 focus:border-primary-500 dark:focus:border-primary-400 focus:ring-primary-200 dark:focus:ring-primary-400/20\";\n };\n\n // Typography class for message\n const getMessageTypographyClass = (): string => {\n if (messageType === \"error\") return \"text-red-500 dark:text-red-400\";\n if (messageType === \"success\")\n return \"text-green-500 dark:text-green-400\";\n if (messageType === \"info\") return \"text-blue-500 dark:text-blue-400\";\n return \"text-neutral-500 dark:text-black-100\";\n };\n\n const inputId = id || `input-${label?.replace(/\\s+/g, \"-\").toLowerCase()}`;\n\n // Effect to measure suffix width and update input padding\n useEffect(() => {\n if (fieldSuffix && suffixRef.current) {\n const resizeObserver = new ResizeObserver((entries) => {\n const suffixElement = entries[0];\n if (suffixElement) {\n // Add extra padding (8px base + 4px buffer) to prevent overlap\n const calculatedWidth =\n Math.ceil(suffixElement.contentRect.width) + 24;\n setSuffixWidth(calculatedWidth);\n }\n });\n\n resizeObserver.observe(suffixRef.current);\n\n // Initial measurement\n const initialWidth = Math.ceil(suffixRef.current.offsetWidth) + 12;\n setSuffixWidth(initialWidth);\n\n return () => {\n resizeObserver.disconnect();\n };\n } else {\n setSuffixWidth(0);\n }\n }, [fieldSuffix]);\n\n // Calculate dynamic padding style\n const getDynamicInputStyle = (): React.CSSProperties => {\n const basePadding = 12; // Default px-3 is 12px\n const rightPadding = fieldSuffix\n ? Math.max(basePadding, suffixWidth)\n : basePadding;\n\n return {\n \"--input-bg-color\": \"var(--tw-bg-opacity, 1) rgb(var(--bg-color))\",\n \"--text-color\": \"#111827\",\n paddingRight: `${rightPadding}px`,\n ...inputStyle,\n } as React.CSSProperties;\n };\n\n return (\n <div className={cn(\"flex flex-col w-full\", wrapperClassNames)}>\n {/* Autofill styles */}\n <style>\n {`\n .input-field input:-webkit-autofill,\n .input-field input:-webkit-autofill:hover,\n .input-field input:-webkit-autofill:focus {\n -webkit-text-fill-color: var(--text-color) !important;\n -webkit-box-shadow: 0 0 0px 1000px var(--input-bg-color) inset !important;\n transition: background-color 5000s ease-in-out 0s;\n }\n \n .dark .input-field input:-webkit-autofill,\n .dark .input-field input:-webkit-autofill:hover,\n .dark .input-field input:-webkit-autofill:focus {\n -webkit-text-fill-color: white !important;\n -webkit-box-shadow: 0 0 0px 1000px var(--input-bg-color) inset !important;\n }\n `}\n </style>\n\n {/* Label */}\n {label ? (\n <label\n htmlFor={inputId}\n className=\"mb-1 text-xs font-medium text-gray-600 dark:text-gray-300 inline-flex items-center gap-1\"\n >\n <div className=\"flex flex-wrap items-center justify-between w-full\">\n <div className=\"inline-flex flex-wrap items-center gap-1\">\n <InputLabel label={label || \"\"} required={required || false} />\n {/* TODO: Add tooltip support when Tooltip component is available */}\n {/* {tooltip && (\n <Tooltip placement=\"top\" title={tooltip}>\n <div className=\"cursor-pointer\">\n <HelpIcon className=\"w-icon-sm h-icon-sm\" />\n </div>\n </Tooltip>\n )} */}\n </div>\n </div>\n </label>\n ) : null}\n\n {/* Input Container */}\n <div className=\"relative input-field\">\n <input\n {...inputProps}\n ref={ref}\n id={inputId}\n type={type}\n value={value}\n defaultValue={defaultValue}\n placeholder={placeholder}\n required={required}\n disabled={disabled}\n max={max}\n min={min}\n onKeyDown={onKeyDown}\n style={getDynamicInputStyle()}\n className={cn(\n // Base styles\n \"border border-solid h-8 rounded-md block w-full pl-3\",\n \"text-sm font-medium text-neutral-900 dark:text-black-100\",\n \"bg-white dark:bg-black-600\",\n \"transition-colors duration-200 ease-in-out\",\n \"focus:outline-none focus:ring-2\",\n\n // State-specific styles\n getInputBorderClasses(),\n\n // Disabled styles\n disabled &&\n \"opacity-70 cursor-not-allowed bg-neutral-50 dark:bg-black-700\",\n\n // Custom classes\n inputClassNames\n )}\n onChange={(e) => onChange(e.target.value)}\n onClick={(e) => e.stopPropagation()}\n />\n\n {/* Suffix Icon */}\n {fieldSuffix && (\n <div\n ref={suffixRef}\n className=\"absolute inset-y-0 right-0 pr-3 flex items-center pointer-events-none\"\n >\n {fieldSuffix}\n </div>\n )}\n </div>\n\n {/* Error Message */}\n <AnimatePresence>\n {message && (\n <motion.div\n initial={{ opacity: 0, y: -10 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: -10 }}\n transition={{ duration: 0.2 }}\n >\n <Typography\n className={cn(\"mt-1\", getMessageTypographyClass())}\n appearance=\"custom\"\n size=\"extra-small\"\n variant=\"medium\"\n >\n {message}\n </Typography>\n </motion.div>\n )}\n </AnimatePresence>\n </div>\n );\n }\n);\n\nInputField.displayName = \"InputField\";\n"],"names":["InputField","forwardRef","id","value","onChange","onKeyDown","message","messageType","defaultValue","disabled","max","min","required","label","type","placeholder","fieldSuffix","wrapperClassNames","inputClassNames","inputStyle","inputProps","ref","suffixRef","useRef","suffixWidth","setSuffixWidth","useState","getInputBorderClasses","getMessageTypographyClass","inputId","useEffect","resizeObserver","entries","suffixElement","calculatedWidth","initialWidth","getDynamicInputStyle","cn","jsx","InputLabel","jsxs","AnimatePresence","motion","Typography"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),b=require("../../../_virtual/index.cjs.js"),n=require("react"),ve=require("antd"),Ce=require("react-i18next"),Se=require("../../data-display/typography/Typography.cjs.js"),ye=require("../../data-display/label/Label.cjs.js"),N=require("@mui/icons-material"),Ie=require("../../icons/AIExtractedIndicator.cjs.js"),ke=require("../../icons/AIStarIcon.cjs.js"),qe=require("../../icons/HelpIcon.cjs.js"),$=require("../../tooltip/Tooltip.cjs.js"),T=require("../../button/IconButton.cjs.js"),Ne=require("../shared/InputLabel.cjs.js"),c=require("../../../utils/confidenceScoreUtils.cjs.js"),$e=require("../../icon/icons.generated.cjs.js"),U=n.forwardRef(({id:W,label:J,placeholder:Q,value:s,onChange:E,errorMessage:f,defaultValue:X,required:z=!1,isRequiredConditional:Y=!1,masterDataName:x,masterDataColumnName:Z,masterDataFormula:o,masterDataFilters:F,tags:G,index:D,tooltip:M="",originalCase:ee=!1,color:V="",isGTN:g=!1,labelClassName:te,gtnName:L=null,isAiExtracted:le=!1,confidenceScore:j,confidenceType:d="high",confidenceTooltip:w,sourceMeta:ne=[],onConfidenceScoreClick:re,disabled:R=!1,reference:se={},isLiveField:oe=!1,onBlur:ae,onAddGTNToDocument:v,riskDetails:a,isRiskAnalysisOpen:C=!1,RiskDetailsCard:B,primaryColorShades:ie,setDisableActions:H,showDeprecatedFieldWarning:O,MasterDataModal:P,parseMasterDataFormula:p},ce)=>{const{t:de}=Ce.useTranslation(),[
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),b=require("../../../_virtual/index.cjs.js"),n=require("react"),ve=require("antd"),Ce=require("react-i18next"),Se=require("../../data-display/typography/Typography.cjs.js"),ye=require("../../data-display/label/Label.cjs.js"),N=require("@mui/icons-material"),Ie=require("../../icons/AIExtractedIndicator.cjs.js"),ke=require("../../icons/AIStarIcon.cjs.js"),qe=require("../../icons/HelpIcon.cjs.js"),$=require("../../tooltip/Tooltip.cjs.js"),T=require("../../button/IconButton.cjs.js"),Ne=require("../shared/InputLabel.cjs.js"),c=require("../../../utils/confidenceScoreUtils.cjs.js"),$e=require("../../icon/icons.generated.cjs.js"),U=n.forwardRef(({id:W,label:J,placeholder:Q,value:s,onChange:E,errorMessage:f,defaultValue:X,required:z=!1,isRequiredConditional:Y=!1,masterDataName:x,masterDataColumnName:Z,masterDataFormula:o,masterDataFilters:F,tags:G,index:D,tooltip:M="",originalCase:ee=!1,color:V="",isGTN:g=!1,labelClassName:te,gtnName:L=null,isAiExtracted:le=!1,confidenceScore:j,confidenceType:d="high",confidenceTooltip:w,sourceMeta:ne=[],onConfidenceScoreClick:re,disabled:R=!1,reference:se={},isLiveField:oe=!1,onBlur:ae,onAddGTNToDocument:v,riskDetails:a,isRiskAnalysisOpen:C=!1,RiskDetailsCard:B,primaryColorShades:ie,setDisableActions:H,showDeprecatedFieldWarning:O,MasterDataModal:P,parseMasterDataFormula:p},ce)=>{const{t:de}=Ce.useTranslation(),[m,S]=n.useState(!1),[r,u]=n.useState(null),[i,A]=n.useState(!1),[ue,fe]=n.useState(""),[y,K]=n.useState(null),[xe,pe]=n.useState(!1),I=n.useRef(null),k=ce||I;n.useEffect(()=>{const t=()=>{const l=k.current||I.current;l&&pe(l.scrollWidth>l.clientWidth)};return t(),window.addEventListener("resize",t),()=>window.removeEventListener("resize",t)},[r,s]),n.useEffect(()=>{u(s)},[D,s]),n.useEffect(()=>{r!==null&&r!==s&&E(r,y)},[r,y]);const q=()=>{H?.(!i),A(!i)},me=t=>{if(t.keyCode===9||t.key==="Enter"){const l=k.current||I.current;l&&(u(ue),l.blur())}},he=(t,l)=>{let h=t;o&&p&&(h=p(o,l)),fe(""),u(h),q(),K(l)},be=()=>{u(""),K(null)},ge=t=>{v&&L&&v({key:L,value:t})},je=()=>{const t="border h-8 text-sm rounded-lg block w-full p-2.5 pr-16 font-inter font-medium",l=f?"border-red-300":C&&a?.color?`border-${a?.color}-300`:"border-gray-300 dark:border-black-600",h="placeholder:text-neutral-900 dark:placeholder:text-black-400",we=`${C&&a?.color?`bg-${a?.color}-50`:"dark:bg-black-600 "} ${V||"text-neutral-900 dark:text-black-200"}`;return`${t} ${l} ${we} ${h}`},_=()=>r!==null?r:o&&p?p(o,se):s;return n.useEffect(()=>{i&&!x&&(O?.(),A(!1))},[i,x,O]),e.jsxs("div",{className:b("flex gap-0.5 w-full relative",m&&g?"border rounded-lg border-primary-100 p-1":"",{"error-field":!!f}),onMouseEnter:()=>S(!0),onMouseLeave:()=>S(!1),children:[g&&!m?e.jsx("div",{className:"w-1 h-1 bg-primary-600 rounded-full animate-blink mt-1.5"}):null,e.jsxs("div",{className:b("flex flex-col w-full"),children:[e.jsx("label",{htmlFor:"text",className:`text-xs font-medium text-gray-600 inline-flex items-center gap-1 ${ee?"":"capitalize"} ${te||""}`,children:e.jsxs("div",{className:"grid w-full grid-cols-[minmax(0,1fr)_auto] items-start gap-x-1",children:[e.jsxs("div",{className:"inline-flex min-w-0 items-center gap-1 flex-wrap",children:[e.jsx(Ne.InputLabel,{label:J||"",required:z||!1,isRequiredConditional:Y||!1}),oe&&e.jsx(N.BoltOutlined,{sx:{fontSize:16,color:"var(--color-primary-600)",rotate:"15deg"}}),le&&!c.shouldShowConfidenceScore(j)&&e.jsx(Ie.AIExtractedIndicator,{}),e.jsx(ye.Label,{labels:G}),M&&e.jsx($,{placement:"top",title:`${M}${o?` | ${o}`:""}`,children:e.jsx("div",{className:"cursor-pointer",children:e.jsx(qe.HelpIcon,{className:"w-icon-sm h-icon-sm"})})})]}),e.jsxs("div",{className:"flex items-center gap-1 justify-self-end",children:[c.shouldShowConfidenceScore(j)&&d?e.jsx($,{placement:"top-end",title:w??"",hideTooltip:w==null,className:"cursor-pointer",children:e.jsxs("div",{className:b("inline-flex min-w-[50px] items-center gap-1 rounded-md px-1 py-0.5",c.getConfidenceScoreBadgeClass(d)),onClick:()=>re?.(ne),children:[e.jsx(ke.AIStarIcon,{size:12,fill:c.getConfidenceScoreBadgeColor(d),fillSecondary:c.getConfidenceScoreBadgeFill(d)}),e.jsxs("span",{className:b("text-xs font-medium leading-4",c.getConfidenceScoreBadgeTextColor(d)),children:[j,"%"]})]})}):null,g&&m&&v?e.jsx("button",{id:"btn-master-data-input-add-to-document",className:"cursor-pointer",onClick:()=>ge(s?.toString()||""),type:"button",children:e.jsx(ve.Tooltip,{placement:"top",title:de("Add to document"),children:e.jsx(N.NoteAddOutlined,{sx:{fontSize:16,color:ie?.[600]||"var(--color-primary-600)"}})})}):null]})]})}),e.jsxs("label",{className:"relative block mt-1",children:[e.jsx($,{title:xe?_():"",children:e.jsx("input",{id:W,ref:k,required:z,placeholder:Q,className:je(),onChange:t=>{E(t.target.value,y),u(t.target?.value)},onKeyDown:me,value:_(),defaultValue:X,disabled:!0,autoComplete:"off",onBlur:ae})}),e.jsx(T,{id:"btn-dynamic-data-input-rx-cross",onClick:be,className:"absolute inset-y-0 right-1 flex items-center px-2 focus:border-transparent",variant:"ghost",disabled:R,children:e.jsx($e.CloseIcon,{className:"w-6 h-6 text-neutral-500 dark:text-neutral-400 w-sm h-sm"})}),e.jsx(T,{id:"btn-dynamic-data-input-ai-outline-pic-center",onClick:q,className:"absolute inset-y-0 right-8 flex items-center px-2 focus:border-transparent",variant:"ghost",disabled:R,children:e.jsx(N.TableChartRounded,{className:"text-neutral-500 dark:text-neutral-400 w-sm h-sm"})})]}),f&&e.jsx(Se.Typography,{className:"text-error-500 mt-1",appearance:"custom",size:"extra-small",variant:"medium",children:f}),i&&P&&e.jsx(P,{isVisible:i,onSelected:he,onClose:q,masterDataColumnName:Z,masterDataFilters:F,masterDataName:x,masterDataId:x,showFilters:!0})]}),m&&a&&C&&B&&e.jsx("div",{role:"tooltip",tabIndex:0,className:"absolute left-0 right-0 top-[95%] mt-1 z-50 bg-white dark:bg-black-600 rounded-xl",onClick:t=>t.stopPropagation(),onMouseDown:t=>t.preventDefault(),onKeyDown:t=>{t.key==="Escape"&&S(!1)},children:e.jsx(B,{riskDetails:a})})]})});U.displayName="MasterDataInputField";exports.MasterDataInputField=U;
|
|
2
2
|
//# sourceMappingURL=MasterDataInputField.cjs.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MasterDataInputField.cjs.js","sources":["../../../../src/components/forms/master-data-input/MasterDataInputField.tsx"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport cn from \"classnames\";\nimport { forwardRef, useEffect, useRef, useState } from \"react\";\nimport { Tooltip as AntTooltip } from \"antd\";\nimport { useTranslation } from 'react-i18next';\nimport { Typography } from \"../../data-display/typography/Typography\";\nimport { Label } from \"../../data-display/label/Label\";\nimport type { LabelType } from \"../../data-display/label/Label\";\nimport {\n BoltOutlined,\n CloseRounded,\n NoteAddOutlined,\n TableChartRounded,\n} from \"@mui/icons-material\";\nimport { AIExtractedIndicator } from \"../../icons/AIExtractedIndicator\";\nimport { AIStarIcon } from \"../../icons/AIStarIcon\";\nimport { HelpIcon } from \"../../icons/HelpIcon\";\nimport Tooltip from \"../../tooltip/Tooltip\";\nimport IconButton from \"../../button/IconButton\";\nimport { InputLabel } from \"../shared/InputLabel\";\nimport {\n getConfidenceScoreBadgeClass,\n getConfidenceScoreBadgeColor,\n getConfidenceScoreBadgeFill,\n getConfidenceScoreBadgeTextColor,\n shouldShowConfidenceScore,\n} from \"../../../utils/confidenceScoreUtils\";\nimport { CloseIcon, CloseSmallIcon } from \"../../icon\";\n\n/**\n * Confidence score type\n */\nexport type ConfidenceScoreType = \"low\" | \"medium\" | \"high\";\n\nexport type SourceMetaBBox = {\n b: number;\n l: number;\n r: number;\n t: number;\n};\n\nexport type SourceMetaItem = {\n bbox: SourceMetaBBox;\n confidence_score?: number;\n is_primary?: boolean;\n match_score?: number;\n match_type?: string;\n page_height: number;\n page_width: number;\n source_page: number;\n source_text?: string;\n};\n\n/**\n * Risk details interface for risk analysis integration\n */\nexport interface RiskDetails {\n color?: string;\n description?: string;\n hexBgColor?: string;\n hexBorderColor?: string;\n [key: string]: any;\n}\n\n/**\n * Risk details card component props - generic to allow consumer-specific risk types\n */\nexport interface RiskDetailsCardProps<T = any> {\n riskDetails: T;\n maxWidth?: string;\n showAllRisksSuggestions?: boolean;\n}\n\n/**\n * Props for the MasterDataModal component\n */\nexport interface MasterDataModalProps {\n isVisible: boolean;\n onSelected?: (masterDataValue: any, masterDataRow?: any) => void;\n onClose: () => void;\n masterDataColumnName?: string;\n masterDataFilters?: any;\n masterDataName?: string;\n masterDataId: string | null;\n showFilters?: boolean;\n}\n\n/**\n * Props for the MasterDataInputField component\n */\nexport interface MasterDataInputFieldProps {\n /** Unique identifier for the input */\n id: string;\n /** Label text to display above the input */\n label: string;\n /** Placeholder text for the input */\n placeholder?: string;\n /** Current value of the input */\n value: any;\n /** Callback function called when value changes */\n onChange: (value: any, masterDataRowValue?: any) => void;\n /** Error message to display below the input */\n errorMessage?: string;\n /** Callback to set error message */\n setErrorMessage: (message: string) => void;\n /** Callback to remove error message */\n removeErrorMessage: () => void;\n /** Default value for the input */\n defaultValue?: any;\n /** Whether the field is required */\n required?: boolean;\n /** Whether the required indicator shows as conditional (yellow instead of red) */\n isRequiredConditional?: boolean;\n /** Name of the master data source */\n masterDataName: string;\n /** Column name in the master data */\n masterDataColumnName: string;\n /** Formula for computing master data value */\n masterDataFormula?: string;\n /** Filters for master data */\n masterDataFilters?: any;\n /** Tags/labels to display next to the label */\n tags?: (string | LabelType)[];\n /** Index for array fields */\n index?: number;\n /** Tooltip text for the help icon */\n tooltip?: string;\n /** Whether to preserve original case in the label */\n originalCase?: boolean;\n /** Color for the input text */\n color?: string;\n /** Whether this is a GTN (Global Term Name) field */\n isGTN?: boolean;\n /** GTN field name for document integration */\n gtnName?: any;\n /** Whether the value was AI extracted */\n isAiExtracted?: boolean;\n /** Confidence percentage shown as a badge */\n confidenceScore?: number;\n /** Confidence classification for badge styling */\n confidenceType?: ConfidenceScoreType;\n /** Optional tooltip content for confidence badge */\n confidenceTooltip?: React.ReactNode;\n /** Source meta for confidence score */\n sourceMeta?: SourceMetaItem[];\n /** Handler fired when confidence score badge is clicked */\n onConfidenceScoreClick?: (sourceMeta: SourceMetaItem[]) => void;\n /** Reference data for formula computation */\n reference?: any;\n /** Whether the input is disabled */\n disabled?: boolean;\n /** Additional CSS classes for the label */\n labelClassName?: string;\n /** Whether this is a live field */\n isLiveField?: boolean;\n /** Callback function called when input loses focus */\n onBlur?: () => void;\n /** Handler for adding GTN to document */\n onAddGTNToDocument?: (keyValuePair: { key: string; value: string }) => void;\n /** Risk details data */\n riskDetails?: RiskDetails;\n /** Whether risk analysis is open */\n isRiskAnalysisOpen?: boolean;\n /** Custom risk details card component */\n RiskDetailsCard?: React.ComponentType<RiskDetailsCardProps<any>>;\n /** Primary color shades for styling */\n primaryColorShades?: Record<number, string>;\n /** Callback to set disable actions state */\n setDisableActions?: (disabled: boolean) => void;\n /** Toast function for deprecated field warning */\n showDeprecatedFieldWarning?: () => void;\n /** Master data modal component */\n MasterDataModal?: React.ComponentType<MasterDataModalProps>;\n /** Function to parse master data formula */\n parseMasterDataFormula?: (formula: string, row: any) => string;\n}\n\n/**\n * A highly customizable master data input component with label, validation, and styling support.\n * Features master data modal integration, GTN support, risk analysis support,\n * and comprehensive prop support for various use cases.\n *\n * @example\n * ```tsx\n * <MasterDataInputField\n * id=\"master-field\"\n * label=\"Master Field\"\n * value={fieldValue}\n * onChange={(value, rowValue) => setFieldValue(value)}\n * setErrorMessage={(msg) => setError(msg)}\n * removeErrorMessage={() => setError('')}\n * masterDataName=\"customers\"\n * masterDataColumnName=\"name\"\n * required\n * />\n * ```\n */\nexport const MasterDataInputField = forwardRef<\n HTMLInputElement,\n MasterDataInputFieldProps\n>(\n (\n {\n id,\n label,\n placeholder,\n value,\n onChange,\n errorMessage,\n defaultValue,\n required = false,\n isRequiredConditional = false,\n masterDataName,\n masterDataColumnName,\n masterDataFormula,\n masterDataFilters,\n tags,\n index,\n tooltip = \"\",\n originalCase = false,\n color = \"\",\n isGTN = false,\n labelClassName,\n gtnName = null,\n isAiExtracted = false,\n confidenceScore,\n confidenceType = \"high\",\n confidenceTooltip,\n sourceMeta = [],\n onConfidenceScoreClick,\n disabled = false,\n reference = {},\n isLiveField = false,\n onBlur,\n onAddGTNToDocument,\n riskDetails,\n isRiskAnalysisOpen = false,\n RiskDetailsCard,\n primaryColorShades,\n setDisableActions,\n showDeprecatedFieldWarning,\n MasterDataModal,\n parseMasterDataFormula,\n },\n ref\n ) => {\n const { t } = useTranslation();\n const [isHovered, setIsHovered] = useState(false);\n const [inputValue, setInputValue] = useState<string | null>(null);\n const [showMasterDataModal, setShowMasterDataModal] = useState(false);\n const [suggestion, setSuggestion] = useState(\"\");\n const [masterDataRowValue, setMasterDataRowValue] = useState<any>(null);\n const [isTextOverflowing, setIsTextOverflowing] = useState(false);\n\n const inputRef = useRef<HTMLInputElement>(null);\n\n // Use forwarded ref or internal ref\n const combinedRef = (ref as React.RefObject<HTMLInputElement>) || inputRef;\n\n // Check if text is overflowing\n useEffect(() => {\n const checkOverflow = () => {\n const input = combinedRef.current || inputRef.current;\n if (input) {\n setIsTextOverflowing(input.scrollWidth > input.clientWidth);\n }\n };\n\n checkOverflow();\n // Recheck on window resize\n window.addEventListener('resize', checkOverflow);\n return () => window.removeEventListener('resize', checkOverflow);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [inputValue, value]);\n\n useEffect(() => {\n setInputValue(value);\n }, [index, value]);\n\n useEffect(() => {\n if (inputValue !== null && inputValue !== value) {\n onChange(inputValue, masterDataRowValue);\n }\n }, [inputValue, masterDataRowValue]);\n\n const toggleMasterDataModal = () => {\n if (showMasterDataModal) {\n setDisableActions?.(false);\n } else {\n setDisableActions?.(true);\n }\n setShowMasterDataModal(!showMasterDataModal);\n };\n\n const handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {\n if (event.keyCode === 9 || event.key === \"Enter\") {\n const currentRef = combinedRef.current || inputRef.current;\n if (currentRef) {\n setInputValue(suggestion);\n currentRef.blur();\n }\n }\n };\n\n const handleSetMasterData = (masterDataValue: any, masterDataRow?: any) => {\n let _value = masterDataValue;\n\n if (masterDataFormula && parseMasterDataFormula) {\n _value = parseMasterDataFormula(masterDataFormula, masterDataRow);\n }\n\n setSuggestion(\"\");\n setInputValue(_value);\n toggleMasterDataModal();\n setMasterDataRowValue(masterDataRow);\n };\n\n const handleClear = () => {\n setInputValue(\"\");\n setMasterDataRowValue(null);\n };\n\n const handleAddGTNToDocument = (_value: string) => {\n if (onAddGTNToDocument && gtnName) {\n const keyValuePair = {\n key: gtnName,\n value: _value,\n };\n onAddGTNToDocument(keyValuePair);\n }\n };\n\n const getClassName = (): string => {\n const baseClasses =\n \"border h-8 text-sm rounded-lg block w-full p-2.5 pr-16 font-inter font-medium\";\n const borderColor = errorMessage\n ? \"border-red-300\"\n : isRiskAnalysisOpen && riskDetails?.color\n ? `border-${riskDetails?.color}-300`\n : \"border-gray-300 dark:border-black-600\";\n const placeholderColor = `placeholder:text-neutral-900 dark:placeholder:text-black-400`;\n const backgroundColor = `${\n isRiskAnalysisOpen && riskDetails?.color\n ? `bg-${riskDetails?.color}-50`\n : \"dark:bg-black-600 \"\n } ${color ? color : \"text-neutral-900 dark:text-black-200\"}`;\n\n return `${baseClasses} ${borderColor} ${backgroundColor} ${placeholderColor}`;\n };\n\n const resolveMasterDataValue = () => {\n if (inputValue !== null) {\n return inputValue;\n }\n if (masterDataFormula && parseMasterDataFormula) {\n return parseMasterDataFormula(masterDataFormula, reference);\n }\n\n return value;\n };\n\n useEffect(() => {\n if (showMasterDataModal && !masterDataName) {\n showDeprecatedFieldWarning?.();\n setShowMasterDataModal(false);\n }\n }, [showMasterDataModal, masterDataName, showDeprecatedFieldWarning]);\n\n return (\n <div\n className={cn(\n `flex gap-0.5 w-full relative`,\n isHovered && isGTN\n ? \"border rounded-lg border-primary-100 p-1\"\n : \"\",\n { \"error-field\": !!errorMessage }\n )}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n >\n {isGTN && !isHovered ? (\n <div className=\"w-1 h-1 bg-primary-600 rounded-full animate-blink mt-1.5\" />\n ) : null}\n\n <div className={cn(`flex flex-col w-full`)}>\n <label\n htmlFor=\"text\"\n className={`text-xs font-medium text-gray-600 inline-flex items-center gap-1 ${\n !originalCase ? \"capitalize\" : \"\"\n } ${labelClassName || \"\"}`}\n >\n <div className=\"grid w-full grid-cols-[minmax(0,1fr)_auto] items-start gap-x-1\">\n <div className=\"inline-flex min-w-0 items-center gap-1 flex-wrap\">\n <InputLabel label={label || \"\"} required={required || false} isRequiredConditional={isRequiredConditional || false} />\n {isLiveField && (\n <BoltOutlined\n sx={{\n fontSize: 16,\n color: \"var(--color-primary-600)\",\n rotate: \"15deg\",\n }}\n />\n )}\n {isAiExtracted && !shouldShowConfidenceScore(confidenceScore) && <AIExtractedIndicator />}\n <Label labels={tags} />\n {tooltip && (\n <Tooltip\n placement=\"top\"\n title={`${tooltip}${masterDataFormula ? ` | ${masterDataFormula}` : \"\"}`}\n >\n <div className=\"cursor-pointer\">\n <HelpIcon />\n </div>\n </Tooltip>\n )}\n </div>\n\n <div className=\"flex items-center gap-1 justify-self-end\">\n {(shouldShowConfidenceScore(confidenceScore) && confidenceType) ? (\n <Tooltip\n placement=\"top-end\"\n title={confidenceTooltip ?? \"\"}\n hideTooltip={confidenceTooltip === undefined || confidenceTooltip === null}\n className=\"cursor-pointer\"\n >\n <div\n className={cn(\n \"inline-flex min-w-[50px] items-center gap-1 rounded-md px-1 py-0.5\",\n getConfidenceScoreBadgeClass(confidenceType)\n )}\n onClick={() => onConfidenceScoreClick?.(sourceMeta)}\n >\n <AIStarIcon\n size={12}\n fill={getConfidenceScoreBadgeColor(confidenceType)}\n fillSecondary={getConfidenceScoreBadgeFill(confidenceType)}\n />\n <span className={cn(\"text-xs font-medium leading-4\", getConfidenceScoreBadgeTextColor(confidenceType))}>\n {confidenceScore}%\n </span>\n </div>\n </Tooltip>\n ) : null}\n {isGTN && isHovered && onAddGTNToDocument ? (\n <button\n id=\"btn-master-data-input-add-to-document\"\n className=\"cursor-pointer\"\n onClick={() => handleAddGTNToDocument(value?.toString() || \"\")}\n type=\"button\"\n >\n <AntTooltip placement=\"top\" title={t(\"Add to document\")}>\n <NoteAddOutlined\n sx={{\n fontSize: 16,\n color:\n primaryColorShades?.[600] || \"var(--color-primary-600)\",\n }}\n />\n </AntTooltip>\n </button>\n ) : null}\n </div>\n </div>\n </label>\n <label className=\"relative block mt-1\">\n <Tooltip\n title={isTextOverflowing ? resolveMasterDataValue() : \"\"}\n >\n <input\n id={id}\n ref={combinedRef}\n required={required}\n placeholder={placeholder}\n className={getClassName()}\n onChange={(e) => {\n onChange(e.target.value, masterDataRowValue);\n setInputValue(e.target?.value);\n }}\n onKeyDown={handleKeyDown}\n value={resolveMasterDataValue()}\n defaultValue={defaultValue}\n disabled={true}\n autoComplete=\"off\"\n onBlur={onBlur}\n />\n </Tooltip>\n\n <IconButton\n id={`btn-dynamic-data-input-rx-cross`}\n onClick={handleClear}\n className=\"absolute inset-y-0 right-1 flex items-center px-2 focus:border-transparent\"\n variant=\"ghost\"\n disabled={disabled}\n >\n <CloseIcon className=\"w-6 h-6 text-neutral-500 dark:text-neutral-400 w-sm h-sm\" />\n </IconButton>\n\n <IconButton\n id={`btn-dynamic-data-input-ai-outline-pic-center`}\n onClick={toggleMasterDataModal}\n className=\"absolute inset-y-0 right-8 flex items-center px-2 focus:border-transparent\"\n variant=\"ghost\"\n disabled={disabled}\n >\n <TableChartRounded\n className=\"text-neutral-500 dark:text-neutral-400 w-sm h-sm\"\n />\n </IconButton>\n </label>\n\n {errorMessage && (\n <Typography\n className=\"text-error-500 mt-1\"\n appearance=\"custom\"\n size=\"extra-small\"\n variant=\"medium\"\n >\n {errorMessage}\n </Typography>\n )}\n\n {showMasterDataModal && MasterDataModal && (\n <MasterDataModal\n isVisible={showMasterDataModal}\n onSelected={handleSetMasterData}\n onClose={toggleMasterDataModal}\n masterDataColumnName={masterDataColumnName}\n masterDataFilters={masterDataFilters}\n masterDataName={masterDataName}\n masterDataId={masterDataName}\n showFilters\n />\n )}\n </div>\n\n {isHovered &&\n riskDetails &&\n isRiskAnalysisOpen &&\n RiskDetailsCard && (\n <div\n role=\"tooltip\"\n tabIndex={0}\n className=\"absolute left-0 right-0 top-[95%] mt-1 z-50 bg-white dark:bg-black-600 rounded-xl\"\n onClick={(e) => e.stopPropagation()}\n onMouseDown={(e) => e.preventDefault()}\n onKeyDown={(e) => {\n if (e.key === \"Escape\") {\n setIsHovered(false);\n }\n }}\n >\n <RiskDetailsCard riskDetails={riskDetails} />\n </div>\n )}\n </div>\n );\n }\n);\n\nMasterDataInputField.displayName = \"MasterDataInputField\";\n\n"],"names":["MasterDataInputField","forwardRef","id","label","placeholder","value","onChange","errorMessage","defaultValue","required","isRequiredConditional","masterDataName","masterDataColumnName","masterDataFormula","masterDataFilters","tags","index","tooltip","originalCase","color","isGTN","labelClassName","gtnName","isAiExtracted","confidenceScore","confidenceType","confidenceTooltip","sourceMeta","onConfidenceScoreClick","disabled","reference","isLiveField","onBlur","onAddGTNToDocument","riskDetails","isRiskAnalysisOpen","RiskDetailsCard","primaryColorShades","setDisableActions","showDeprecatedFieldWarning","MasterDataModal","parseMasterDataFormula","ref","t","useTranslation","isHovered","setIsHovered","useState","inputValue","setInputValue","showMasterDataModal","setShowMasterDataModal","suggestion","setSuggestion","masterDataRowValue","setMasterDataRowValue","isTextOverflowing","setIsTextOverflowing","inputRef","useRef","combinedRef","useEffect","checkOverflow","input","toggleMasterDataModal","handleKeyDown","event","currentRef","handleSetMasterData","masterDataValue","masterDataRow","_value","handleClear","handleAddGTNToDocument","getClassName","baseClasses","borderColor","placeholderColor","backgroundColor","resolveMasterDataValue","jsxs","cn","jsx","InputLabel","BoltOutlined","shouldShowConfidenceScore","AIExtractedIndicator","Label","Tooltip","HelpIcon","getConfidenceScoreBadgeClass","AIStarIcon","getConfidenceScoreBadgeColor","getConfidenceScoreBadgeFill","getConfidenceScoreBadgeTextColor","AntTooltip","NoteAddOutlined","e","IconButton","CloseIcon","TableChartRounded","Typography"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"MasterDataInputField.cjs.js","sources":["../../../../src/components/forms/master-data-input/MasterDataInputField.tsx"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport cn from \"classnames\";\nimport { forwardRef, useEffect, useRef, useState } from \"react\";\nimport { Tooltip as AntTooltip } from \"antd\";\nimport { useTranslation } from 'react-i18next';\nimport { Typography } from \"../../data-display/typography/Typography\";\nimport { Label } from \"../../data-display/label/Label\";\nimport type { LabelType } from \"../../data-display/label/Label\";\nimport {\n BoltOutlined,\n CloseRounded,\n NoteAddOutlined,\n TableChartRounded,\n} from \"@mui/icons-material\";\nimport { AIExtractedIndicator } from \"../../icons/AIExtractedIndicator\";\nimport { AIStarIcon } from \"../../icons/AIStarIcon\";\nimport { HelpIcon } from \"../../icons/HelpIcon\";\nimport Tooltip from \"../../tooltip/Tooltip\";\nimport IconButton from \"../../button/IconButton\";\nimport { InputLabel } from \"../shared/InputLabel\";\nimport {\n getConfidenceScoreBadgeClass,\n getConfidenceScoreBadgeColor,\n getConfidenceScoreBadgeFill,\n getConfidenceScoreBadgeTextColor,\n shouldShowConfidenceScore,\n} from \"../../../utils/confidenceScoreUtils\";\nimport { CloseIcon, CloseSmallIcon } from \"../../icon\";\n\n/**\n * Confidence score type\n */\nexport type ConfidenceScoreType = \"low\" | \"medium\" | \"high\";\n\nexport type SourceMetaBBox = {\n b: number;\n l: number;\n r: number;\n t: number;\n};\n\nexport type SourceMetaItem = {\n bbox: SourceMetaBBox;\n confidence_score?: number;\n is_primary?: boolean;\n match_score?: number;\n match_type?: string;\n page_height: number;\n page_width: number;\n source_page: number;\n source_text?: string;\n};\n\n/**\n * Risk details interface for risk analysis integration\n */\nexport interface RiskDetails {\n color?: string;\n description?: string;\n hexBgColor?: string;\n hexBorderColor?: string;\n [key: string]: any;\n}\n\n/**\n * Risk details card component props - generic to allow consumer-specific risk types\n */\nexport interface RiskDetailsCardProps<T = any> {\n riskDetails: T;\n maxWidth?: string;\n showAllRisksSuggestions?: boolean;\n}\n\n/**\n * Props for the MasterDataModal component\n */\nexport interface MasterDataModalProps {\n isVisible: boolean;\n onSelected?: (masterDataValue: any, masterDataRow?: any) => void;\n onClose: () => void;\n masterDataColumnName?: string;\n masterDataFilters?: any;\n masterDataName?: string;\n masterDataId: string | null;\n showFilters?: boolean;\n}\n\n/**\n * Props for the MasterDataInputField component\n */\nexport interface MasterDataInputFieldProps {\n /** Unique identifier for the input */\n id: string;\n /** Label text to display above the input */\n label: string;\n /** Placeholder text for the input */\n placeholder?: string;\n /** Current value of the input */\n value: any;\n /** Callback function called when value changes */\n onChange: (value: any, masterDataRowValue?: any) => void;\n /** Error message to display below the input */\n errorMessage?: string;\n /** Callback to set error message */\n setErrorMessage: (message: string) => void;\n /** Callback to remove error message */\n removeErrorMessage: () => void;\n /** Default value for the input */\n defaultValue?: any;\n /** Whether the field is required */\n required?: boolean;\n /** Whether the required indicator shows as conditional (yellow instead of red) */\n isRequiredConditional?: boolean;\n /** Name of the master data source */\n masterDataName: string;\n /** Column name in the master data */\n masterDataColumnName: string;\n /** Formula for computing master data value */\n masterDataFormula?: string;\n /** Filters for master data */\n masterDataFilters?: any;\n /** Tags/labels to display next to the label */\n tags?: (string | LabelType)[];\n /** Index for array fields */\n index?: number;\n /** Tooltip text for the help icon */\n tooltip?: string;\n /** Whether to preserve original case in the label */\n originalCase?: boolean;\n /** Color for the input text */\n color?: string;\n /** Whether this is a GTN (Global Term Name) field */\n isGTN?: boolean;\n /** GTN field name for document integration */\n gtnName?: any;\n /** Whether the value was AI extracted */\n isAiExtracted?: boolean;\n /** Confidence percentage shown as a badge */\n confidenceScore?: number;\n /** Confidence classification for badge styling */\n confidenceType?: ConfidenceScoreType;\n /** Optional tooltip content for confidence badge */\n confidenceTooltip?: React.ReactNode;\n /** Source meta for confidence score */\n sourceMeta?: SourceMetaItem[];\n /** Handler fired when confidence score badge is clicked */\n onConfidenceScoreClick?: (sourceMeta: SourceMetaItem[]) => void;\n /** Reference data for formula computation */\n reference?: any;\n /** Whether the input is disabled */\n disabled?: boolean;\n /** Additional CSS classes for the label */\n labelClassName?: string;\n /** Whether this is a live field */\n isLiveField?: boolean;\n /** Callback function called when input loses focus */\n onBlur?: () => void;\n /** Handler for adding GTN to document */\n onAddGTNToDocument?: (keyValuePair: { key: string; value: string }) => void;\n /** Risk details data */\n riskDetails?: RiskDetails;\n /** Whether risk analysis is open */\n isRiskAnalysisOpen?: boolean;\n /** Custom risk details card component */\n RiskDetailsCard?: React.ComponentType<RiskDetailsCardProps<any>>;\n /** Primary color shades for styling */\n primaryColorShades?: Record<number, string>;\n /** Callback to set disable actions state */\n setDisableActions?: (disabled: boolean) => void;\n /** Toast function for deprecated field warning */\n showDeprecatedFieldWarning?: () => void;\n /** Master data modal component */\n MasterDataModal?: React.ComponentType<MasterDataModalProps>;\n /** Function to parse master data formula */\n parseMasterDataFormula?: (formula: string, row: any) => string;\n}\n\n/**\n * A highly customizable master data input component with label, validation, and styling support.\n * Features master data modal integration, GTN support, risk analysis support,\n * and comprehensive prop support for various use cases.\n *\n * @example\n * ```tsx\n * <MasterDataInputField\n * id=\"master-field\"\n * label=\"Master Field\"\n * value={fieldValue}\n * onChange={(value, rowValue) => setFieldValue(value)}\n * setErrorMessage={(msg) => setError(msg)}\n * removeErrorMessage={() => setError('')}\n * masterDataName=\"customers\"\n * masterDataColumnName=\"name\"\n * required\n * />\n * ```\n */\nexport const MasterDataInputField = forwardRef<\n HTMLInputElement,\n MasterDataInputFieldProps\n>(\n (\n {\n id,\n label,\n placeholder,\n value,\n onChange,\n errorMessage,\n defaultValue,\n required = false,\n isRequiredConditional = false,\n masterDataName,\n masterDataColumnName,\n masterDataFormula,\n masterDataFilters,\n tags,\n index,\n tooltip = \"\",\n originalCase = false,\n color = \"\",\n isGTN = false,\n labelClassName,\n gtnName = null,\n isAiExtracted = false,\n confidenceScore,\n confidenceType = \"high\",\n confidenceTooltip,\n sourceMeta = [],\n onConfidenceScoreClick,\n disabled = false,\n reference = {},\n isLiveField = false,\n onBlur,\n onAddGTNToDocument,\n riskDetails,\n isRiskAnalysisOpen = false,\n RiskDetailsCard,\n primaryColorShades,\n setDisableActions,\n showDeprecatedFieldWarning,\n MasterDataModal,\n parseMasterDataFormula,\n },\n ref\n ) => {\n const { t } = useTranslation();\n const [isHovered, setIsHovered] = useState(false);\n const [inputValue, setInputValue] = useState<string | null>(null);\n const [showMasterDataModal, setShowMasterDataModal] = useState(false);\n const [suggestion, setSuggestion] = useState(\"\");\n const [masterDataRowValue, setMasterDataRowValue] = useState<any>(null);\n const [isTextOverflowing, setIsTextOverflowing] = useState(false);\n\n const inputRef = useRef<HTMLInputElement>(null);\n\n // Use forwarded ref or internal ref\n const combinedRef = (ref as React.RefObject<HTMLInputElement>) || inputRef;\n\n // Check if text is overflowing\n useEffect(() => {\n const checkOverflow = () => {\n const input = combinedRef.current || inputRef.current;\n if (input) {\n setIsTextOverflowing(input.scrollWidth > input.clientWidth);\n }\n };\n\n checkOverflow();\n // Recheck on window resize\n window.addEventListener('resize', checkOverflow);\n return () => window.removeEventListener('resize', checkOverflow);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [inputValue, value]);\n\n useEffect(() => {\n setInputValue(value);\n }, [index, value]);\n\n useEffect(() => {\n if (inputValue !== null && inputValue !== value) {\n onChange(inputValue, masterDataRowValue);\n }\n }, [inputValue, masterDataRowValue]);\n\n const toggleMasterDataModal = () => {\n if (showMasterDataModal) {\n setDisableActions?.(false);\n } else {\n setDisableActions?.(true);\n }\n setShowMasterDataModal(!showMasterDataModal);\n };\n\n const handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {\n if (event.keyCode === 9 || event.key === \"Enter\") {\n const currentRef = combinedRef.current || inputRef.current;\n if (currentRef) {\n setInputValue(suggestion);\n currentRef.blur();\n }\n }\n };\n\n const handleSetMasterData = (masterDataValue: any, masterDataRow?: any) => {\n let _value = masterDataValue;\n\n if (masterDataFormula && parseMasterDataFormula) {\n _value = parseMasterDataFormula(masterDataFormula, masterDataRow);\n }\n\n setSuggestion(\"\");\n setInputValue(_value);\n toggleMasterDataModal();\n setMasterDataRowValue(masterDataRow);\n };\n\n const handleClear = () => {\n setInputValue(\"\");\n setMasterDataRowValue(null);\n };\n\n const handleAddGTNToDocument = (_value: string) => {\n if (onAddGTNToDocument && gtnName) {\n const keyValuePair = {\n key: gtnName,\n value: _value,\n };\n onAddGTNToDocument(keyValuePair);\n }\n };\n\n const getClassName = (): string => {\n const baseClasses =\n \"border h-8 text-sm rounded-lg block w-full p-2.5 pr-16 font-inter font-medium\";\n const borderColor = errorMessage\n ? \"border-red-300\"\n : isRiskAnalysisOpen && riskDetails?.color\n ? `border-${riskDetails?.color}-300`\n : \"border-gray-300 dark:border-black-600\";\n const placeholderColor = `placeholder:text-neutral-900 dark:placeholder:text-black-400`;\n const backgroundColor = `${\n isRiskAnalysisOpen && riskDetails?.color\n ? `bg-${riskDetails?.color}-50`\n : \"dark:bg-black-600 \"\n } ${color ? color : \"text-neutral-900 dark:text-black-200\"}`;\n\n return `${baseClasses} ${borderColor} ${backgroundColor} ${placeholderColor}`;\n };\n\n const resolveMasterDataValue = () => {\n if (inputValue !== null) {\n return inputValue;\n }\n if (masterDataFormula && parseMasterDataFormula) {\n return parseMasterDataFormula(masterDataFormula, reference);\n }\n\n return value;\n };\n\n useEffect(() => {\n if (showMasterDataModal && !masterDataName) {\n showDeprecatedFieldWarning?.();\n setShowMasterDataModal(false);\n }\n }, [showMasterDataModal, masterDataName, showDeprecatedFieldWarning]);\n\n return (\n <div\n className={cn(\n `flex gap-0.5 w-full relative`,\n isHovered && isGTN\n ? \"border rounded-lg border-primary-100 p-1\"\n : \"\",\n { \"error-field\": !!errorMessage }\n )}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n >\n {isGTN && !isHovered ? (\n <div className=\"w-1 h-1 bg-primary-600 rounded-full animate-blink mt-1.5\" />\n ) : null}\n\n <div className={cn(`flex flex-col w-full`)}>\n <label\n htmlFor=\"text\"\n className={`text-xs font-medium text-gray-600 inline-flex items-center gap-1 ${\n !originalCase ? \"capitalize\" : \"\"\n } ${labelClassName || \"\"}`}\n >\n <div className=\"grid w-full grid-cols-[minmax(0,1fr)_auto] items-start gap-x-1\">\n <div className=\"inline-flex min-w-0 items-center gap-1 flex-wrap\">\n <InputLabel label={label || \"\"} required={required || false} isRequiredConditional={isRequiredConditional || false} />\n {isLiveField && (\n <BoltOutlined\n sx={{\n fontSize: 16,\n color: \"var(--color-primary-600)\",\n rotate: \"15deg\",\n }}\n />\n )}\n {isAiExtracted && !shouldShowConfidenceScore(confidenceScore) && <AIExtractedIndicator />}\n <Label labels={tags} />\n {tooltip && (\n <Tooltip\n placement=\"top\"\n title={`${tooltip}${masterDataFormula ? ` | ${masterDataFormula}` : \"\"}`}\n >\n <div className=\"cursor-pointer\">\n <HelpIcon className=\"w-icon-sm h-icon-sm\" />\n </div>\n </Tooltip>\n )}\n </div>\n\n <div className=\"flex items-center gap-1 justify-self-end\">\n {(shouldShowConfidenceScore(confidenceScore) && confidenceType) ? (\n <Tooltip\n placement=\"top-end\"\n title={confidenceTooltip ?? \"\"}\n hideTooltip={confidenceTooltip === undefined || confidenceTooltip === null}\n className=\"cursor-pointer\"\n >\n <div\n className={cn(\n \"inline-flex min-w-[50px] items-center gap-1 rounded-md px-1 py-0.5\",\n getConfidenceScoreBadgeClass(confidenceType)\n )}\n onClick={() => onConfidenceScoreClick?.(sourceMeta)}\n >\n <AIStarIcon\n size={12}\n fill={getConfidenceScoreBadgeColor(confidenceType)}\n fillSecondary={getConfidenceScoreBadgeFill(confidenceType)}\n />\n <span className={cn(\"text-xs font-medium leading-4\", getConfidenceScoreBadgeTextColor(confidenceType))}>\n {confidenceScore}%\n </span>\n </div>\n </Tooltip>\n ) : null}\n {isGTN && isHovered && onAddGTNToDocument ? (\n <button\n id=\"btn-master-data-input-add-to-document\"\n className=\"cursor-pointer\"\n onClick={() => handleAddGTNToDocument(value?.toString() || \"\")}\n type=\"button\"\n >\n <AntTooltip placement=\"top\" title={t(\"Add to document\")}>\n <NoteAddOutlined\n sx={{\n fontSize: 16,\n color:\n primaryColorShades?.[600] || \"var(--color-primary-600)\",\n }}\n />\n </AntTooltip>\n </button>\n ) : null}\n </div>\n </div>\n </label>\n <label className=\"relative block mt-1\">\n <Tooltip\n title={isTextOverflowing ? resolveMasterDataValue() : \"\"}\n >\n <input\n id={id}\n ref={combinedRef}\n required={required}\n placeholder={placeholder}\n className={getClassName()}\n onChange={(e) => {\n onChange(e.target.value, masterDataRowValue);\n setInputValue(e.target?.value);\n }}\n onKeyDown={handleKeyDown}\n value={resolveMasterDataValue()}\n defaultValue={defaultValue}\n disabled={true}\n autoComplete=\"off\"\n onBlur={onBlur}\n />\n </Tooltip>\n\n <IconButton\n id={`btn-dynamic-data-input-rx-cross`}\n onClick={handleClear}\n className=\"absolute inset-y-0 right-1 flex items-center px-2 focus:border-transparent\"\n variant=\"ghost\"\n disabled={disabled}\n >\n <CloseIcon className=\"w-6 h-6 text-neutral-500 dark:text-neutral-400 w-sm h-sm\" />\n </IconButton>\n\n <IconButton\n id={`btn-dynamic-data-input-ai-outline-pic-center`}\n onClick={toggleMasterDataModal}\n className=\"absolute inset-y-0 right-8 flex items-center px-2 focus:border-transparent\"\n variant=\"ghost\"\n disabled={disabled}\n >\n <TableChartRounded\n className=\"text-neutral-500 dark:text-neutral-400 w-sm h-sm\"\n />\n </IconButton>\n </label>\n\n {errorMessage && (\n <Typography\n className=\"text-error-500 mt-1\"\n appearance=\"custom\"\n size=\"extra-small\"\n variant=\"medium\"\n >\n {errorMessage}\n </Typography>\n )}\n\n {showMasterDataModal && MasterDataModal && (\n <MasterDataModal\n isVisible={showMasterDataModal}\n onSelected={handleSetMasterData}\n onClose={toggleMasterDataModal}\n masterDataColumnName={masterDataColumnName}\n masterDataFilters={masterDataFilters}\n masterDataName={masterDataName}\n masterDataId={masterDataName}\n showFilters\n />\n )}\n </div>\n\n {isHovered &&\n riskDetails &&\n isRiskAnalysisOpen &&\n RiskDetailsCard && (\n <div\n role=\"tooltip\"\n tabIndex={0}\n className=\"absolute left-0 right-0 top-[95%] mt-1 z-50 bg-white dark:bg-black-600 rounded-xl\"\n onClick={(e) => e.stopPropagation()}\n onMouseDown={(e) => e.preventDefault()}\n onKeyDown={(e) => {\n if (e.key === \"Escape\") {\n setIsHovered(false);\n }\n }}\n >\n <RiskDetailsCard riskDetails={riskDetails} />\n </div>\n )}\n </div>\n );\n }\n);\n\nMasterDataInputField.displayName = \"MasterDataInputField\";\n\n"],"names":["MasterDataInputField","forwardRef","id","label","placeholder","value","onChange","errorMessage","defaultValue","required","isRequiredConditional","masterDataName","masterDataColumnName","masterDataFormula","masterDataFilters","tags","index","tooltip","originalCase","color","isGTN","labelClassName","gtnName","isAiExtracted","confidenceScore","confidenceType","confidenceTooltip","sourceMeta","onConfidenceScoreClick","disabled","reference","isLiveField","onBlur","onAddGTNToDocument","riskDetails","isRiskAnalysisOpen","RiskDetailsCard","primaryColorShades","setDisableActions","showDeprecatedFieldWarning","MasterDataModal","parseMasterDataFormula","ref","t","useTranslation","isHovered","setIsHovered","useState","inputValue","setInputValue","showMasterDataModal","setShowMasterDataModal","suggestion","setSuggestion","masterDataRowValue","setMasterDataRowValue","isTextOverflowing","setIsTextOverflowing","inputRef","useRef","combinedRef","useEffect","checkOverflow","input","toggleMasterDataModal","handleKeyDown","event","currentRef","handleSetMasterData","masterDataValue","masterDataRow","_value","handleClear","handleAddGTNToDocument","getClassName","baseClasses","borderColor","placeholderColor","backgroundColor","resolveMasterDataValue","jsxs","cn","jsx","InputLabel","BoltOutlined","shouldShowConfidenceScore","AIExtractedIndicator","Label","Tooltip","HelpIcon","getConfidenceScoreBadgeClass","AIStarIcon","getConfidenceScoreBadgeColor","getConfidenceScoreBadgeFill","getConfidenceScoreBadgeTextColor","AntTooltip","NoteAddOutlined","e","IconButton","CloseIcon","TableChartRounded","Typography"],"mappings":"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"}
|
|
@@ -130,7 +130,7 @@ const Pe = Ce(
|
|
|
130
130
|
{
|
|
131
131
|
placement: "top",
|
|
132
132
|
title: `${M}${a ? ` | ${a}` : ""}`,
|
|
133
|
-
children: /* @__PURE__ */ e("div", { className: "cursor-pointer", children: /* @__PURE__ */ e(Me, {}) })
|
|
133
|
+
children: /* @__PURE__ */ e("div", { className: "cursor-pointer", children: /* @__PURE__ */ e(Me, { className: "w-icon-sm h-icon-sm" }) })
|
|
134
134
|
}
|
|
135
135
|
)
|
|
136
136
|
] }),
|