@ryanhe919/lumen-ui 0.3.1 → 0.3.2

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.
Files changed (178) hide show
  1. package/LICENSE +21 -0
  2. package/dist/ErrorMessage-CbE7emgD.cjs +26 -0
  3. package/dist/ErrorMessage-CbE7emgD.cjs.map +1 -0
  4. package/dist/ErrorMessage-Dt4cJ-sy.js +27 -0
  5. package/dist/ErrorMessage-Dt4cJ-sy.js.map +1 -0
  6. package/dist/{LMButton-B258yfky.cjs → LMButton-ByInEqMk.cjs} +15 -11
  7. package/dist/LMButton-ByInEqMk.cjs.map +1 -0
  8. package/dist/{LMButton-S4xQSohi.js → LMButton-DH7s4i80.js} +16 -12
  9. package/dist/LMButton-DH7s4i80.js.map +1 -0
  10. package/dist/{LMCard-D_K051f2.cjs → LMCard-lJGrsAzY.cjs} +9 -6
  11. package/dist/LMCard-lJGrsAzY.cjs.map +1 -0
  12. package/dist/{LMCard-D7ABNC95.js → LMCard-uuWNjVQL.js} +9 -6
  13. package/dist/LMCard-uuWNjVQL.js.map +1 -0
  14. package/dist/{LMCheckbox-C2YvEQ8f.cjs → LMCheckbox-C5gRhXJk.cjs} +11 -34
  15. package/dist/LMCheckbox-C5gRhXJk.cjs.map +1 -0
  16. package/dist/{LMCheckbox-DaaJRjKt.js → LMCheckbox-DPg4CldM.js} +11 -34
  17. package/dist/LMCheckbox-DPg4CldM.js.map +1 -0
  18. package/dist/{LMDatePicker-DSv28BFH.js → LMDatePicker-C7R0ByJ-.js} +5 -1
  19. package/dist/LMDatePicker-C7R0ByJ-.js.map +1 -0
  20. package/dist/{LMDatePicker-BlUwN4On.cjs → LMDatePicker-lH-8-HzG.cjs} +5 -1
  21. package/dist/LMDatePicker-lH-8-HzG.cjs.map +1 -0
  22. package/dist/{LMEmpty-BedQxpbi.cjs → LMEmpty-BCf4K8iH.cjs} +7 -6
  23. package/dist/LMEmpty-BCf4K8iH.cjs.map +1 -0
  24. package/dist/{LMEmpty-DzHM1fOb.js → LMEmpty-C499qRrR.js} +7 -6
  25. package/dist/LMEmpty-C499qRrR.js.map +1 -0
  26. package/dist/{LMField-DhDHj64z.cjs → LMField-BRaviP2p.cjs} +3 -2
  27. package/dist/LMField-BRaviP2p.cjs.map +1 -0
  28. package/dist/{LMField-BS-DSEya.js → LMField-DkRk9Q8-.js} +3 -2
  29. package/dist/LMField-DkRk9Q8-.js.map +1 -0
  30. package/dist/{LMInput-D9csGyhj.js → LMInput-Be2KkPOW.js} +21 -43
  31. package/dist/LMInput-Be2KkPOW.js.map +1 -0
  32. package/dist/{LMInput-CVjawj1F.cjs → LMInput-O55xkiRS.cjs} +20 -42
  33. package/dist/LMInput-O55xkiRS.cjs.map +1 -0
  34. package/dist/{LMModal-BCVVPLot.cjs → LMModal-BgxF1xOT.cjs} +2 -2
  35. package/dist/LMModal-BgxF1xOT.cjs.map +1 -0
  36. package/dist/{LMModal-DCJPlfA4.js → LMModal-CZF26Ask.js} +2 -2
  37. package/dist/LMModal-CZF26Ask.js.map +1 -0
  38. package/dist/{LMNumberInput-B1tU7T_W.cjs → LMNumberInput-DQaLVoud.cjs} +30 -39
  39. package/dist/LMNumberInput-DQaLVoud.cjs.map +1 -0
  40. package/dist/{LMNumberInput-BI5_OEx4.js → LMNumberInput-gnRvWRly.js} +31 -40
  41. package/dist/LMNumberInput-gnRvWRly.js.map +1 -0
  42. package/dist/{LMRadio-CHn6nFSy.cjs → LMRadio-BVBwm1rk.cjs} +11 -37
  43. package/dist/LMRadio-BVBwm1rk.cjs.map +1 -0
  44. package/dist/{LMRadio-UQLNgTMF.js → LMRadio-C0ZL0hVK.js} +11 -37
  45. package/dist/LMRadio-C0ZL0hVK.js.map +1 -0
  46. package/dist/{LMSearchInput-nBlAX734.cjs → LMSearchInput-BDJVh4Vs.cjs} +25 -31
  47. package/dist/LMSearchInput-BDJVh4Vs.cjs.map +1 -0
  48. package/dist/{LMSearchInput-CIvVkEf2.js → LMSearchInput-DQovqMTN.js} +26 -32
  49. package/dist/LMSearchInput-DQovqMTN.js.map +1 -0
  50. package/dist/{LMSelect-B-MWX2JI.js → LMSelect-BPfW-AHI.js} +37 -48
  51. package/dist/LMSelect-BPfW-AHI.js.map +1 -0
  52. package/dist/{LMSelect-ByQcUp2S.cjs → LMSelect-xIVolEhx.cjs} +37 -48
  53. package/dist/LMSelect-xIVolEhx.cjs.map +1 -0
  54. package/dist/{LMStatCard-D5HV9r6d.js → LMStatCard-CdyIDhrA.js} +11 -6
  55. package/dist/LMStatCard-CdyIDhrA.js.map +1 -0
  56. package/dist/{LMStatCard-MXs9Z0qH.cjs → LMStatCard-Do5f2Map.cjs} +11 -6
  57. package/dist/LMStatCard-Do5f2Map.cjs.map +1 -0
  58. package/dist/{LMSwitch-CP1_nrfU.js → LMSwitch-BqhucDO0.js} +3 -31
  59. package/dist/LMSwitch-BqhucDO0.js.map +1 -0
  60. package/dist/{LMSwitch-DYoSH6wE.cjs → LMSwitch-BxVqTSUH.cjs} +3 -31
  61. package/dist/LMSwitch-BxVqTSUH.cjs.map +1 -0
  62. package/dist/{LMTable-j1ZzAzXB.cjs → LMTable-Be9FK8bz.cjs} +7 -4
  63. package/dist/LMTable-Be9FK8bz.cjs.map +1 -0
  64. package/dist/{LMTable-Cp8HZqiV.js → LMTable-IGmHFhnV.js} +7 -4
  65. package/dist/LMTable-IGmHFhnV.js.map +1 -0
  66. package/dist/{LMTabs-D5n9lB8X.js → LMTabs-Cjp3oiNv.js} +2 -2
  67. package/dist/{LMTabs-D5n9lB8X.js.map → LMTabs-Cjp3oiNv.js.map} +1 -1
  68. package/dist/{LMTabs-NPmOzPat.cjs → LMTabs-DEYx2gOH.cjs} +2 -2
  69. package/dist/{LMTabs-NPmOzPat.cjs.map → LMTabs-DEYx2gOH.cjs.map} +1 -1
  70. package/dist/{LMTextarea-5dVVPeL2.js → LMTextarea-BNacTCNn.js} +20 -28
  71. package/dist/LMTextarea-BNacTCNn.js.map +1 -0
  72. package/dist/{LMTextarea-yG0OBZjA.cjs → LMTextarea-DRi6gaFW.cjs} +20 -28
  73. package/dist/LMTextarea-DRi6gaFW.cjs.map +1 -0
  74. package/dist/cn-I2jp-M-K.cjs +6 -0
  75. package/dist/cn-I2jp-M-K.cjs.map +1 -0
  76. package/dist/cn-wDEkOmcn.js +7 -0
  77. package/dist/cn-wDEkOmcn.js.map +1 -0
  78. package/dist/components/Chat/LMChatBubble/LMChatBubble.d.ts.map +1 -1
  79. package/dist/components/Chat/LMChatContainer/LMChatContainer.d.ts.map +1 -1
  80. package/dist/components/Chat/LMChatInput/LMChatInput.d.ts.map +1 -1
  81. package/dist/components/Chat/LMChatMessage/LMChatMessage.d.ts.map +1 -1
  82. package/dist/components/Chat/LMMarkdownRenderer/LMMarkdownRenderer.d.ts.map +1 -1
  83. package/dist/components/Chat/LMTypingIndicator/LMTypingIndicator.d.ts.map +1 -1
  84. package/dist/components/DataDisplay/LMCard/LMCard.d.ts.map +1 -1
  85. package/dist/components/DataDisplay/LMEmpty/LMEmpty.d.ts.map +1 -1
  86. package/dist/components/DataDisplay/LMStatCard/LMStatCard.d.ts.map +1 -1
  87. package/dist/components/DataDisplay/LMTable/LMTable.d.ts.map +1 -1
  88. package/dist/components/Feedback/LMModal/LMModal.d.ts +1 -1
  89. package/dist/components/Feedback/LMModal/LMModal.d.ts.map +1 -1
  90. package/dist/components/Form/LMCheckbox/LMCheckbox.d.ts.map +1 -1
  91. package/dist/components/Form/LMDatePicker/LMDatePicker.d.ts.map +1 -1
  92. package/dist/components/Form/LMField/LMField.d.ts.map +1 -1
  93. package/dist/components/Form/LMInput/LMInput.d.ts +1 -1
  94. package/dist/components/Form/LMInput/LMInput.d.ts.map +1 -1
  95. package/dist/components/Form/LMNumberInput/LMNumberInput.d.ts +1 -1
  96. package/dist/components/Form/LMNumberInput/LMNumberInput.d.ts.map +1 -1
  97. package/dist/components/Form/LMRadio/LMRadio.d.ts.map +1 -1
  98. package/dist/components/Form/LMSearchInput/LMSearchInput.d.ts +1 -1
  99. package/dist/components/Form/LMSearchInput/LMSearchInput.d.ts.map +1 -1
  100. package/dist/components/Form/LMSelect/LMSelect.d.ts.map +1 -1
  101. package/dist/components/Form/LMSwitch/LMSwitch.d.ts.map +1 -1
  102. package/dist/components/Form/LMTextarea/LMTextarea.d.ts +1 -1
  103. package/dist/components/Form/LMTextarea/LMTextarea.d.ts.map +1 -1
  104. package/dist/components/General/LMButton/LMButton.d.ts.map +1 -1
  105. package/dist/components/_internal/ErrorMessage.d.ts +9 -0
  106. package/dist/components/_internal/ErrorMessage.d.ts.map +1 -0
  107. package/dist/components/button/index.cjs +1 -1
  108. package/dist/components/button/index.js +1 -1
  109. package/dist/components/card/index.cjs +1 -1
  110. package/dist/components/card/index.js +1 -1
  111. package/dist/components/checkbox/index.cjs +1 -1
  112. package/dist/components/checkbox/index.js +1 -1
  113. package/dist/components/date-picker/index.cjs +1 -1
  114. package/dist/components/date-picker/index.js +1 -1
  115. package/dist/components/empty/index.cjs +1 -1
  116. package/dist/components/empty/index.js +1 -1
  117. package/dist/components/field/index.cjs +1 -1
  118. package/dist/components/field/index.js +1 -1
  119. package/dist/components/input/index.cjs +1 -1
  120. package/dist/components/input/index.js +1 -1
  121. package/dist/components/modal/index.cjs +1 -1
  122. package/dist/components/modal/index.js +1 -1
  123. package/dist/components/number-input/index.cjs +1 -1
  124. package/dist/components/number-input/index.js +1 -1
  125. package/dist/components/radio/index.cjs +1 -1
  126. package/dist/components/radio/index.js +1 -1
  127. package/dist/components/search-input/index.cjs +1 -1
  128. package/dist/components/search-input/index.js +1 -1
  129. package/dist/components/select/index.cjs +1 -1
  130. package/dist/components/select/index.js +1 -1
  131. package/dist/components/stat-card/index.cjs +1 -1
  132. package/dist/components/stat-card/index.js +1 -1
  133. package/dist/components/switch/index.cjs +1 -1
  134. package/dist/components/switch/index.js +1 -1
  135. package/dist/components/table/index.cjs +1 -1
  136. package/dist/components/table/index.js +1 -1
  137. package/dist/components/tabs/index.cjs +1 -1
  138. package/dist/components/tabs/index.js +1 -1
  139. package/dist/components/textarea/index.cjs +1 -1
  140. package/dist/components/textarea/index.js +1 -1
  141. package/dist/index.cjs +120 -121
  142. package/dist/index.cjs.map +1 -1
  143. package/dist/index.js +119 -120
  144. package/dist/index.js.map +1 -1
  145. package/dist/style.css +6 -0
  146. package/package.json +8 -7
  147. package/dist/LMButton-B258yfky.cjs.map +0 -1
  148. package/dist/LMButton-S4xQSohi.js.map +0 -1
  149. package/dist/LMCard-D7ABNC95.js.map +0 -1
  150. package/dist/LMCard-D_K051f2.cjs.map +0 -1
  151. package/dist/LMCheckbox-C2YvEQ8f.cjs.map +0 -1
  152. package/dist/LMCheckbox-DaaJRjKt.js.map +0 -1
  153. package/dist/LMDatePicker-BlUwN4On.cjs.map +0 -1
  154. package/dist/LMDatePicker-DSv28BFH.js.map +0 -1
  155. package/dist/LMEmpty-BedQxpbi.cjs.map +0 -1
  156. package/dist/LMEmpty-DzHM1fOb.js.map +0 -1
  157. package/dist/LMField-BS-DSEya.js.map +0 -1
  158. package/dist/LMField-DhDHj64z.cjs.map +0 -1
  159. package/dist/LMInput-CVjawj1F.cjs.map +0 -1
  160. package/dist/LMInput-D9csGyhj.js.map +0 -1
  161. package/dist/LMModal-BCVVPLot.cjs.map +0 -1
  162. package/dist/LMModal-DCJPlfA4.js.map +0 -1
  163. package/dist/LMNumberInput-B1tU7T_W.cjs.map +0 -1
  164. package/dist/LMNumberInput-BI5_OEx4.js.map +0 -1
  165. package/dist/LMRadio-CHn6nFSy.cjs.map +0 -1
  166. package/dist/LMRadio-UQLNgTMF.js.map +0 -1
  167. package/dist/LMSearchInput-CIvVkEf2.js.map +0 -1
  168. package/dist/LMSearchInput-nBlAX734.cjs.map +0 -1
  169. package/dist/LMSelect-B-MWX2JI.js.map +0 -1
  170. package/dist/LMSelect-ByQcUp2S.cjs.map +0 -1
  171. package/dist/LMStatCard-D5HV9r6d.js.map +0 -1
  172. package/dist/LMStatCard-MXs9Z0qH.cjs.map +0 -1
  173. package/dist/LMSwitch-CP1_nrfU.js.map +0 -1
  174. package/dist/LMSwitch-DYoSH6wE.cjs.map +0 -1
  175. package/dist/LMTable-Cp8HZqiV.js.map +0 -1
  176. package/dist/LMTable-j1ZzAzXB.cjs.map +0 -1
  177. package/dist/LMTextarea-5dVVPeL2.js.map +0 -1
  178. package/dist/LMTextarea-yG0OBZjA.cjs.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LMInput-O55xkiRS.cjs","sources":["../src/components/Form/LMInput/LMInput.tsx"],"sourcesContent":["import React, { useId } from 'react'\nimport { cn } from '../../../utils/cn'\nimport { SIZE_INPUT_CONFIG } from '../../../utils/componentSizes'\nimport type { ComponentSize } from '../../../utils/componentSizes'\nimport { ErrorMessage } from '../../_internal/ErrorMessage'\n\nexport interface LMInputProps\n extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'size'> {\n /** Left icon */\n leftIcon?: React.ReactNode\n /** Right element */\n rightElement?: React.ReactNode\n /** Error state */\n error?: boolean\n /** Error message */\n errorMessage?: string\n /** Size */\n size?: ComponentSize\n /** Include seconds for time inputs */\n includeSeconds?: boolean\n}\n\nconst LMInput = React.forwardRef<HTMLInputElement, LMInputProps>(({\n leftIcon,\n rightElement,\n error = false,\n errorMessage,\n className = '',\n size = 'md',\n includeSeconds = false,\n ...props\n}, ref) => {\n const hasLeftIcon = !!leftIcon\n const hasRightElement = !!rightElement\n const errorId = `lm-input-err-${useId()}`\n\n const timeInputProps = () => {\n if (\n (props.type === 'datetime-local' || props.type === 'time') &&\n includeSeconds\n ) {\n return { step: '1' as const }\n }\n return {}\n }\n\n // Apple-like refined input styling\n const baseClassName = cn(\n 'w-full',\n SIZE_INPUT_CONFIG[size].padding,\n SIZE_INPUT_CONFIG[size].height,\n SIZE_INPUT_CONFIG[size].fontSize,\n 'border rounded-xl',\n 'focus:ring-2 focus:outline-none',\n hasLeftIcon && 'pl-10',\n hasRightElement && 'pr-10',\n className\n )\n\n const getInputStyles = () => {\n // Apple-like refined input styles\n const baseStyles = {\n backgroundColor: 'var(--lm-bg-elevated)',\n color: 'var(--lm-text-primary)',\n borderColor: error\n ? 'var(--lm-error-300)'\n : 'var(--lm-border-default)',\n boxShadow: 'var(--lm-shadow-sm)',\n transition: 'all var(--lm-transition-fast) var(--lm-ease-out)',\n } as React.CSSProperties\n\n return {\n ...baseStyles,\n '--tw-ring-color': error\n ? 'var(--lm-error-400)'\n : 'var(--lm-primary-400)',\n '--tw-ring-opacity': '0.4',\n }\n }\n\n const getDisabledStyles = () =>\n props.disabled\n ? {\n backgroundColor: 'var(--lm-bg-paper)',\n color: 'var(--lm-text-disabled)',\n cursor: 'not-allowed',\n opacity: 0.6,\n }\n : {}\n\n const getIconStyles = () =>\n error\n ? { color: 'var(--lm-error-400)' }\n : { color: 'var(--lm-text-secondary)' }\n\n return (\n <div className=\"space-y-2\">\n <div className=\"relative group\">\n {hasLeftIcon && (\n <div className=\"absolute inset-y-0 left-0 pl-4 flex items-center pointer-events-none z-10\">\n <div\n className=\"transition-colors duration-200\"\n style={getIconStyles()}\n >\n {leftIcon}\n </div>\n </div>\n )}\n\n <input\n ref={ref}\n {...props}\n {...timeInputProps()}\n className={baseClassName}\n aria-invalid={error || undefined}\n aria-describedby={errorMessage ? errorId : undefined}\n style={{\n ...getInputStyles(),\n ...getDisabledStyles(),\n } as React.CSSProperties}\n onMouseEnter={(e) => {\n if (!props.disabled && !error) {\n e.currentTarget.style.borderColor = 'var(--lm-border-strong)'\n }\n props.onMouseEnter?.(e)\n }}\n onMouseLeave={(e) => {\n if (!props.disabled && !error) {\n e.currentTarget.style.borderColor = 'var(--lm-border-default)'\n }\n props.onMouseLeave?.(e)\n }}\n onFocus={(e) => {\n if (!props.disabled) {\n e.currentTarget.style.borderColor = error\n ? 'var(--lm-error-400)'\n : 'var(--lm-primary-400)'\n }\n props.onFocus?.(e)\n }}\n onBlur={(e) => {\n if (!props.disabled) {\n e.currentTarget.style.borderColor = error\n ? 'var(--lm-error-300)'\n : 'var(--lm-border-default)'\n }\n props.onBlur?.(e)\n }}\n />\n\n {hasRightElement && (\n <div className=\"absolute inset-y-0 right-0 pr-4 flex items-center z-10\">\n {rightElement}\n </div>\n )}\n </div>\n\n {errorMessage && <ErrorMessage message={errorMessage} id={errorId} />}\n </div>\n )\n})\n\nLMInput.displayName = 'LMInput'\n\nexport default LMInput\n"],"names":["useId","cn","SIZE_INPUT_CONFIG","jsxs","jsx","ErrorMessage"],"mappings":"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"}
@@ -2,7 +2,7 @@
2
2
  const jsxRuntime = require("react/jsx-runtime");
3
3
  const React = require("react");
4
4
  const reactDom = require("react-dom");
5
- const LMButton = require("./LMButton-B258yfky.cjs");
5
+ const LMButton = require("./LMButton-ByInEqMk.cjs");
6
6
  const componentSizes = require("./componentSizes-DUTZ7uEM.cjs");
7
7
  const MODAL_FOOTER_SIZE_MAP = {
8
8
  xs: "xs",
@@ -200,4 +200,4 @@ const LMModal = ({
200
200
  };
201
201
  const LMModal_default = React.memo(LMModal);
202
202
  exports.LMModal_default = LMModal_default;
203
- //# sourceMappingURL=LMModal-BCVVPLot.cjs.map
203
+ //# sourceMappingURL=LMModal-BgxF1xOT.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LMModal-BgxF1xOT.cjs","sources":["../src/components/Feedback/LMModal/LMModal.tsx"],"sourcesContent":["import React, { useEffect, useRef, useCallback, memo } from 'react'\nimport { createPortal } from 'react-dom'\nimport { LMButton } from '../../General/LMButton'\nimport {\n COMPONENT_SIZE_ORDER,\n SIZE_HEADING_CLASSES,\n SIZE_MODAL_CONFIG,\n clampComponentSize,\n} from '../../../utils/componentSizes'\nimport type { ComponentSize } from '../../../utils/componentSizes'\n\nconst MODAL_FOOTER_SIZE_MAP: Record<ComponentSize, ComponentSize> = {\n xs: 'xs',\n sm: 'xs',\n md: 'sm',\n lg: 'md',\n xl: 'md',\n '2xl': 'lg',\n}\n\nconst CloseIcon: React.FC = () => (\n <svg className=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n)\n\nconst WindowIcon: React.FC = () => (\n <svg className=\"w-5 h-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M4 6h16M4 12h16M4 18h16\" />\n </svg>\n)\n\nexport interface LMModalProps {\n /** Visibility */\n visible: boolean\n /** Title */\n title?: string\n /** Content */\n children: React.ReactNode\n /** Custom footer */\n footer?: React.ReactNode\n /** Close callback */\n onClose?: () => void\n /** OK callback */\n onOk?: () => void\n /** Cancel callback */\n onCancel?: () => void\n /** OK button text */\n okText?: string\n /** Cancel button text */\n cancelText?: string\n /** Show OK button */\n showOk?: boolean\n /** Show Cancel button */\n showCancel?: boolean\n /** OK loading state */\n okLoading?: boolean\n /** Cancel loading state */\n cancelLoading?: boolean\n /** Show mask */\n mask?: boolean\n /** Click mask to close */\n maskClosable?: boolean\n /** Show close button */\n closable?: boolean\n /** Custom close icon */\n closeIcon?: React.ReactNode\n /** Header icon */\n headerIcon?: React.ReactNode\n /** Width */\n width?: string | number\n /** Height */\n height?: string | number\n /** Size preset */\n size?: ComponentSize\n /** Custom class name */\n className?: string\n /** Custom style */\n style?: React.CSSProperties\n /** Center vertically */\n centered?: boolean\n /** Fullscreen mode */\n fullscreen?: boolean\n /** @deprecated Animation duration is now controlled by CSS variables. This prop is kept for backward compatibility. */\n animationDuration?: number\n /** Enable animation */\n animation?: boolean\n}\n\nconst LMModal: React.FC<LMModalProps> = ({\n visible,\n title,\n children,\n footer,\n onClose,\n onOk,\n onCancel,\n okText = 'Confirm',\n cancelText = 'Cancel',\n showOk = true,\n showCancel = true,\n okLoading = false,\n cancelLoading = false,\n mask = true,\n maskClosable = false,\n closable = true,\n closeIcon,\n headerIcon,\n width,\n height,\n size = 'md',\n className = '',\n style,\n centered = true,\n fullscreen = false,\n animationDuration: _animationDuration = 300,\n animation = true,\n}) => {\n // Note: animationDuration is kept for API compatibility but uses CSS variables now\n void _animationDuration\n const modalRef = useRef<HTMLDivElement>(null)\n const backdropRef = useRef<HTMLDivElement>(null)\n const resolvedSize = clampComponentSize(size, COMPONENT_SIZE_ORDER)\n const footerButtonSize = MODAL_FOOTER_SIZE_MAP[resolvedSize]\n\n const getModalStyles = () => {\n // Apple-like refined modal styling\n const baseStyles: React.CSSProperties = {\n backgroundColor: 'var(--lm-bg-elevated)',\n color: 'var(--lm-text-primary)',\n borderColor: 'var(--lm-border-default)',\n boxShadow: 'var(--lm-shadow-xl)',\n borderRadius: 'var(--lm-radius-xl)',\n border: '1px solid var(--lm-border-default)',\n backdropFilter: 'blur(20px) saturate(180%)',\n WebkitBackdropFilter: 'blur(20px) saturate(180%)',\n ...style,\n }\n\n if (fullscreen) {\n baseStyles.width = '100vw'\n baseStyles.height = '100vh'\n baseStyles.maxWidth = '100vw'\n baseStyles.maxHeight = '100vh'\n baseStyles.borderRadius = '0'\n } else {\n baseStyles.width = width\n ? typeof width === 'number'\n ? `${width}px`\n : width\n : SIZE_MODAL_CONFIG[resolvedSize].width\n baseStyles.maxWidth = SIZE_MODAL_CONFIG[resolvedSize].maxWidth\n if (height) {\n baseStyles.height = typeof height === 'number' ? `${height}px` : height\n }\n }\n\n return baseStyles\n }\n\n // Apple-like refined backdrop\n const getBackdropStyles = () =>\n mask\n ? {\n backgroundColor: 'rgba(0, 0, 0, 0.4)',\n backdropFilter: 'blur(8px) saturate(150%)',\n WebkitBackdropFilter: 'blur(8px) saturate(150%)',\n }\n : { backgroundColor: 'transparent', backdropFilter: 'none' }\n\n const handleOk = () => (onOk ? onOk() : onClose?.())\n\n const handleCancel = useCallback(() => {\n if (onCancel) onCancel()\n else onClose?.()\n }, [onCancel, onClose])\n\n const handleBackdropClick = (e: React.MouseEvent) => {\n if (maskClosable && e.target === backdropRef.current) handleCancel()\n }\n\n useEffect(() => {\n const keyHandler = (e: KeyboardEvent) => {\n if (visible && e.key === 'Escape') handleCancel()\n }\n if (visible) {\n document.addEventListener('keydown', keyHandler)\n document.body.style.overflow = 'hidden'\n }\n return () => {\n document.removeEventListener('keydown', keyHandler)\n if (visible) document.body.style.overflow = ''\n }\n }, [visible, handleCancel])\n\n const defaultFooter = (\n <div\n className=\"flex items-center justify-end gap-3 px-6 py-4 border-t\"\n style={{ borderColor: 'var(--lm-border-default)' }}\n >\n {showCancel && (\n <LMButton\n variant=\"secondary\"\n size={footerButtonSize}\n onClick={handleCancel}\n disabled={cancelLoading}\n loading={cancelLoading}\n >\n {cancelText}\n </LMButton>\n )}\n {showOk && (\n <LMButton\n variant=\"primary\"\n size={footerButtonSize}\n onClick={handleOk}\n disabled={okLoading}\n loading={okLoading}\n >\n {okText}\n </LMButton>\n )}\n </div>\n )\n\n // Apple-like refined animation with spring easing\n const getAnimationClasses = () => {\n if (!animation) return ''\n // Use faster, snappier duration for Apple-like feel\n return 'transition-all duration-200 ease-out'\n }\n\n if (!visible) return null\n\n const modalContent = (\n <div\n ref={backdropRef}\n className={`fixed inset-0 z-50 flex ${centered ? 'items-center' : 'items-start pt-20'} justify-center ${getAnimationClasses()}`}\n style={getBackdropStyles()}\n onClick={handleBackdropClick}\n >\n <div\n ref={modalRef}\n className={`relative ${getAnimationClasses()} ${className}`}\n style={getModalStyles()}\n onClick={(e) => e.stopPropagation()}\n >\n {(title || closable) && (\n <div\n className=\"flex items-center justify-between p-6 pb-4 border-b\"\n style={{ borderColor: 'var(--lm-border-default)' }}\n >\n {title && (\n <h3\n className={`font-semibold flex items-center gap-2 ${SIZE_HEADING_CLASSES[resolvedSize]}`}\n style={{ color: 'var(--lm-text-primary)' }}\n >\n <span style={{ color: 'var(--lm-text-secondary)' }}>\n {headerIcon || <WindowIcon />}\n </span>\n {title}\n </h3>\n )}\n {closable && (\n <LMButton\n variant=\"ghost\"\n size=\"xs\"\n onClick={handleCancel}\n leftIcon={closeIcon || <CloseIcon />}\n className=\"w-8 h-8 p-0\"\n aria-label=\"Close dialog\"\n title=\"Close\"\n style={{\n borderRadius: '0.5rem',\n backgroundColor: 'var(--lm-bg-paper)',\n borderColor: 'var(--lm-border-default)',\n color: 'var(--lm-text-secondary)',\n }}\n />\n )}\n </div>\n )}\n\n <div className=\"p-6\">{children}</div>\n\n {footer !== undefined\n ? footer\n : showOk || showCancel\n ? defaultFooter\n : null}\n </div>\n </div>\n )\n\n return createPortal(modalContent, document.body)\n}\n\nexport default memo(LMModal)\n"],"names":["jsx","useRef","clampComponentSize","COMPONENT_SIZE_ORDER","SIZE_MODAL_CONFIG","useCallback","useEffect","jsxs","LMButton","SIZE_HEADING_CLASSES","createPortal","memo"],"mappings":";;;;;;AAWA,MAAM,wBAA8D;AAAA,EAClE,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,OAAO;AACT;AAEA,MAAM,YAAsB,MAC1BA,2BAAAA,IAAC,OAAA,EAAI,WAAU,WAAU,MAAK,QAAO,QAAO,gBAAe,SAAQ,aACjE,UAAAA,2BAAAA,IAAC,QAAA,EAAK,eAAc,SAAQ,gBAAe,SAAQ,aAAa,GAAG,GAAE,uBAAA,CAAuB,EAAA,CAC9F;AAGF,MAAM,aAAuB,MAC3BA,2BAAAA,IAAC,OAAA,EAAI,WAAU,WAAU,MAAK,QAAO,QAAO,gBAAe,SAAQ,aACjE,UAAAA,2BAAAA,IAAC,QAAA,EAAK,eAAc,SAAQ,gBAAe,SAAQ,aAAa,GAAG,GAAE,0BAAA,CAA0B,EAAA,CACjG;AA4DF,MAAM,UAAkC,CAAC;AAAA,EACvC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,SAAS;AAAA,EACT,aAAa;AAAA,EACb,SAAS;AAAA,EACT,aAAa;AAAA,EACb,YAAY;AAAA,EACZ,gBAAgB;AAAA,EAChB,OAAO;AAAA,EACP,eAAe;AAAA,EACf,WAAW;AAAA,EACX;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP,YAAY;AAAA,EACZ;AAAA,EACA,WAAW;AAAA,EACX,aAAa;AAAA,EACb,mBAAmB,qBAAqB;AAAA,EACxC,YAAY;AACd,MAAM;AAGJ,QAAM,WAAWC,MAAAA,OAAuB,IAAI;AAC5C,QAAM,cAAcA,MAAAA,OAAuB,IAAI;AAC/C,QAAM,eAAeC,eAAAA,mBAAmB,MAAMC,mCAAoB;AAClE,QAAM,mBAAmB,sBAAsB,YAAY;AAE3D,QAAM,iBAAiB,MAAM;AAE3B,UAAM,aAAkC;AAAA,MACtC,iBAAiB;AAAA,MACjB,OAAO;AAAA,MACP,aAAa;AAAA,MACb,WAAW;AAAA,MACX,cAAc;AAAA,MACd,QAAQ;AAAA,MACR,gBAAgB;AAAA,MAChB,sBAAsB;AAAA,MACtB,GAAG;AAAA,IAAA;AAGL,QAAI,YAAY;AACd,iBAAW,QAAQ;AACnB,iBAAW,SAAS;AACpB,iBAAW,WAAW;AACtB,iBAAW,YAAY;AACvB,iBAAW,eAAe;AAAA,IAC5B,OAAO;AACL,iBAAW,QAAQ,QACf,OAAO,UAAU,WACf,GAAG,KAAK,OACR,QACFC,eAAAA,kBAAkB,YAAY,EAAE;AACpC,iBAAW,WAAWA,iCAAkB,YAAY,EAAE;AACtD,UAAI,QAAQ;AACV,mBAAW,SAAS,OAAO,WAAW,WAAW,GAAG,MAAM,OAAO;AAAA,MACnE;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAGA,QAAM,oBAAoB,MACxB,OACI;AAAA,IACE,iBAAiB;AAAA,IACjB,gBAAgB;AAAA,IAChB,sBAAsB;AAAA,EAAA,IAExB,EAAE,iBAAiB,eAAe,gBAAgB,OAAA;AAExD,QAAM,WAAW,MAAO,OAAO,KAAA,IAAS;AAExC,QAAM,eAAeC,MAAAA,YAAY,MAAM;AACrC,QAAI,SAAU,UAAA;AAAA,QACT;AAAA,EACP,GAAG,CAAC,UAAU,OAAO,CAAC;AAEtB,QAAM,sBAAsB,CAAC,MAAwB;AACnD,QAAI,gBAAgB,EAAE,WAAW,YAAY,QAAS,cAAA;AAAA,EACxD;AAEAC,QAAAA,UAAU,MAAM;AACd,UAAM,aAAa,CAAC,MAAqB;AACvC,UAAI,WAAW,EAAE,QAAQ,SAAU,cAAA;AAAA,IACrC;AACA,QAAI,SAAS;AACX,eAAS,iBAAiB,WAAW,UAAU;AAC/C,eAAS,KAAK,MAAM,WAAW;AAAA,IACjC;AACA,WAAO,MAAM;AACX,eAAS,oBAAoB,WAAW,UAAU;AAClD,UAAI,QAAS,UAAS,KAAK,MAAM,WAAW;AAAA,IAC9C;AAAA,EACF,GAAG,CAAC,SAAS,YAAY,CAAC;AAE1B,QAAM,gBACJC,2BAAAA;AAAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAU;AAAA,MACV,OAAO,EAAE,aAAa,2BAAA;AAAA,MAErB,UAAA;AAAA,QAAA,cACCP,2BAAAA;AAAAA,UAACQ,SAAAA;AAAAA,UAAA;AAAA,YACC,SAAQ;AAAA,YACR,MAAM;AAAA,YACN,SAAS;AAAA,YACT,UAAU;AAAA,YACV,SAAS;AAAA,YAER,UAAA;AAAA,UAAA;AAAA,QAAA;AAAA,QAGJ,UACCR,2BAAAA;AAAAA,UAACQ,SAAAA;AAAAA,UAAA;AAAA,YACC,SAAQ;AAAA,YACR,MAAM;AAAA,YACN,SAAS;AAAA,YACT,UAAU;AAAA,YACV,SAAS;AAAA,YAER,UAAA;AAAA,UAAA;AAAA,QAAA;AAAA,MACH;AAAA,IAAA;AAAA,EAAA;AAMN,QAAM,sBAAsB,MAAM;AAChC,QAAI,CAAC,UAAW,QAAO;AAEvB,WAAO;AAAA,EACT;AAEA,MAAI,CAAC,QAAS,QAAO;AAErB,QAAM,eACJR,2BAAAA;AAAAA,IAAC;AAAA,IAAA;AAAA,MACC,KAAK;AAAA,MACL,WAAW,2BAA2B,WAAW,iBAAiB,mBAAmB,mBAAmB,qBAAqB;AAAA,MAC7H,OAAO,kBAAA;AAAA,MACP,SAAS;AAAA,MAET,UAAAO,2BAAAA;AAAAA,QAAC;AAAA,QAAA;AAAA,UACC,KAAK;AAAA,UACL,WAAW,YAAY,oBAAA,CAAqB,IAAI,SAAS;AAAA,UACzD,OAAO,eAAA;AAAA,UACP,SAAS,CAAC,MAAM,EAAE,gBAAA;AAAA,UAEhB,UAAA;AAAA,aAAA,SAAS,aACTA,2BAAAA;AAAAA,cAAC;AAAA,cAAA;AAAA,gBACC,WAAU;AAAA,gBACV,OAAO,EAAE,aAAa,2BAAA;AAAA,gBAErB,UAAA;AAAA,kBAAA,SACCA,2BAAAA;AAAAA,oBAAC;AAAA,oBAAA;AAAA,sBACC,WAAW,yCAAyCE,oCAAqB,YAAY,CAAC;AAAA,sBACtF,OAAO,EAAE,OAAO,yBAAA;AAAA,sBAEhB,UAAA;AAAA,wBAAAT,2BAAAA,IAAC,QAAA,EAAK,OAAO,EAAE,OAAO,8BACnB,UAAA,cAAcA,2BAAAA,IAAC,YAAA,CAAA,CAAW,EAAA,CAC7B;AAAA,wBACC;AAAA,sBAAA;AAAA,oBAAA;AAAA,kBAAA;AAAA,kBAGJ,YACCA,2BAAAA;AAAAA,oBAACQ,SAAAA;AAAAA,oBAAA;AAAA,sBACC,SAAQ;AAAA,sBACR,MAAK;AAAA,sBACL,SAAS;AAAA,sBACT,UAAU,aAAaR,+BAAC,WAAA,CAAA,CAAU;AAAA,sBAClC,WAAU;AAAA,sBACV,cAAW;AAAA,sBACX,OAAM;AAAA,sBACN,OAAO;AAAA,wBACL,cAAc;AAAA,wBACd,iBAAiB;AAAA,wBACjB,aAAa;AAAA,wBACb,OAAO;AAAA,sBAAA;AAAA,oBACT;AAAA,kBAAA;AAAA,gBACF;AAAA,cAAA;AAAA,YAAA;AAAA,YAKNA,2BAAAA,IAAC,OAAA,EAAI,WAAU,OAAO,SAAA,CAAS;AAAA,YAE9B,WAAW,SACR,SACA,UAAU,aACR,gBACA;AAAA,UAAA;AAAA,QAAA;AAAA,MAAA;AAAA,IACR;AAAA,EAAA;AAIJ,SAAOU,sBAAa,cAAc,SAAS,IAAI;AACjD;AAEA,MAAA,kBAAeC,MAAAA,KAAK,OAAO;;"}
@@ -1,7 +1,7 @@
1
1
  import { jsx, jsxs } from "react/jsx-runtime";
2
2
  import { memo, useRef, useCallback, useEffect } from "react";
3
3
  import { createPortal } from "react-dom";
4
- import { L as LMButton } from "./LMButton-S4xQSohi.js";
4
+ import { L as LMButton } from "./LMButton-DH7s4i80.js";
5
5
  import { c as clampComponentSize, i as SIZE_HEADING_CLASSES, j as SIZE_MODAL_CONFIG, C as COMPONENT_SIZE_ORDER } from "./componentSizes-CdWNL526.js";
6
6
  const MODAL_FOOTER_SIZE_MAP = {
7
7
  xs: "xs",
@@ -201,4 +201,4 @@ const LMModal_default = memo(LMModal);
201
201
  export {
202
202
  LMModal_default as L
203
203
  };
204
- //# sourceMappingURL=LMModal-DCJPlfA4.js.map
204
+ //# sourceMappingURL=LMModal-CZF26Ask.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LMModal-CZF26Ask.js","sources":["../src/components/Feedback/LMModal/LMModal.tsx"],"sourcesContent":["import React, { useEffect, useRef, useCallback, memo } from 'react'\nimport { createPortal } from 'react-dom'\nimport { LMButton } from '../../General/LMButton'\nimport {\n COMPONENT_SIZE_ORDER,\n SIZE_HEADING_CLASSES,\n SIZE_MODAL_CONFIG,\n clampComponentSize,\n} from '../../../utils/componentSizes'\nimport type { ComponentSize } from '../../../utils/componentSizes'\n\nconst MODAL_FOOTER_SIZE_MAP: Record<ComponentSize, ComponentSize> = {\n xs: 'xs',\n sm: 'xs',\n md: 'sm',\n lg: 'md',\n xl: 'md',\n '2xl': 'lg',\n}\n\nconst CloseIcon: React.FC = () => (\n <svg className=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n)\n\nconst WindowIcon: React.FC = () => (\n <svg className=\"w-5 h-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M4 6h16M4 12h16M4 18h16\" />\n </svg>\n)\n\nexport interface LMModalProps {\n /** Visibility */\n visible: boolean\n /** Title */\n title?: string\n /** Content */\n children: React.ReactNode\n /** Custom footer */\n footer?: React.ReactNode\n /** Close callback */\n onClose?: () => void\n /** OK callback */\n onOk?: () => void\n /** Cancel callback */\n onCancel?: () => void\n /** OK button text */\n okText?: string\n /** Cancel button text */\n cancelText?: string\n /** Show OK button */\n showOk?: boolean\n /** Show Cancel button */\n showCancel?: boolean\n /** OK loading state */\n okLoading?: boolean\n /** Cancel loading state */\n cancelLoading?: boolean\n /** Show mask */\n mask?: boolean\n /** Click mask to close */\n maskClosable?: boolean\n /** Show close button */\n closable?: boolean\n /** Custom close icon */\n closeIcon?: React.ReactNode\n /** Header icon */\n headerIcon?: React.ReactNode\n /** Width */\n width?: string | number\n /** Height */\n height?: string | number\n /** Size preset */\n size?: ComponentSize\n /** Custom class name */\n className?: string\n /** Custom style */\n style?: React.CSSProperties\n /** Center vertically */\n centered?: boolean\n /** Fullscreen mode */\n fullscreen?: boolean\n /** @deprecated Animation duration is now controlled by CSS variables. This prop is kept for backward compatibility. */\n animationDuration?: number\n /** Enable animation */\n animation?: boolean\n}\n\nconst LMModal: React.FC<LMModalProps> = ({\n visible,\n title,\n children,\n footer,\n onClose,\n onOk,\n onCancel,\n okText = 'Confirm',\n cancelText = 'Cancel',\n showOk = true,\n showCancel = true,\n okLoading = false,\n cancelLoading = false,\n mask = true,\n maskClosable = false,\n closable = true,\n closeIcon,\n headerIcon,\n width,\n height,\n size = 'md',\n className = '',\n style,\n centered = true,\n fullscreen = false,\n animationDuration: _animationDuration = 300,\n animation = true,\n}) => {\n // Note: animationDuration is kept for API compatibility but uses CSS variables now\n void _animationDuration\n const modalRef = useRef<HTMLDivElement>(null)\n const backdropRef = useRef<HTMLDivElement>(null)\n const resolvedSize = clampComponentSize(size, COMPONENT_SIZE_ORDER)\n const footerButtonSize = MODAL_FOOTER_SIZE_MAP[resolvedSize]\n\n const getModalStyles = () => {\n // Apple-like refined modal styling\n const baseStyles: React.CSSProperties = {\n backgroundColor: 'var(--lm-bg-elevated)',\n color: 'var(--lm-text-primary)',\n borderColor: 'var(--lm-border-default)',\n boxShadow: 'var(--lm-shadow-xl)',\n borderRadius: 'var(--lm-radius-xl)',\n border: '1px solid var(--lm-border-default)',\n backdropFilter: 'blur(20px) saturate(180%)',\n WebkitBackdropFilter: 'blur(20px) saturate(180%)',\n ...style,\n }\n\n if (fullscreen) {\n baseStyles.width = '100vw'\n baseStyles.height = '100vh'\n baseStyles.maxWidth = '100vw'\n baseStyles.maxHeight = '100vh'\n baseStyles.borderRadius = '0'\n } else {\n baseStyles.width = width\n ? typeof width === 'number'\n ? `${width}px`\n : width\n : SIZE_MODAL_CONFIG[resolvedSize].width\n baseStyles.maxWidth = SIZE_MODAL_CONFIG[resolvedSize].maxWidth\n if (height) {\n baseStyles.height = typeof height === 'number' ? `${height}px` : height\n }\n }\n\n return baseStyles\n }\n\n // Apple-like refined backdrop\n const getBackdropStyles = () =>\n mask\n ? {\n backgroundColor: 'rgba(0, 0, 0, 0.4)',\n backdropFilter: 'blur(8px) saturate(150%)',\n WebkitBackdropFilter: 'blur(8px) saturate(150%)',\n }\n : { backgroundColor: 'transparent', backdropFilter: 'none' }\n\n const handleOk = () => (onOk ? onOk() : onClose?.())\n\n const handleCancel = useCallback(() => {\n if (onCancel) onCancel()\n else onClose?.()\n }, [onCancel, onClose])\n\n const handleBackdropClick = (e: React.MouseEvent) => {\n if (maskClosable && e.target === backdropRef.current) handleCancel()\n }\n\n useEffect(() => {\n const keyHandler = (e: KeyboardEvent) => {\n if (visible && e.key === 'Escape') handleCancel()\n }\n if (visible) {\n document.addEventListener('keydown', keyHandler)\n document.body.style.overflow = 'hidden'\n }\n return () => {\n document.removeEventListener('keydown', keyHandler)\n if (visible) document.body.style.overflow = ''\n }\n }, [visible, handleCancel])\n\n const defaultFooter = (\n <div\n className=\"flex items-center justify-end gap-3 px-6 py-4 border-t\"\n style={{ borderColor: 'var(--lm-border-default)' }}\n >\n {showCancel && (\n <LMButton\n variant=\"secondary\"\n size={footerButtonSize}\n onClick={handleCancel}\n disabled={cancelLoading}\n loading={cancelLoading}\n >\n {cancelText}\n </LMButton>\n )}\n {showOk && (\n <LMButton\n variant=\"primary\"\n size={footerButtonSize}\n onClick={handleOk}\n disabled={okLoading}\n loading={okLoading}\n >\n {okText}\n </LMButton>\n )}\n </div>\n )\n\n // Apple-like refined animation with spring easing\n const getAnimationClasses = () => {\n if (!animation) return ''\n // Use faster, snappier duration for Apple-like feel\n return 'transition-all duration-200 ease-out'\n }\n\n if (!visible) return null\n\n const modalContent = (\n <div\n ref={backdropRef}\n className={`fixed inset-0 z-50 flex ${centered ? 'items-center' : 'items-start pt-20'} justify-center ${getAnimationClasses()}`}\n style={getBackdropStyles()}\n onClick={handleBackdropClick}\n >\n <div\n ref={modalRef}\n className={`relative ${getAnimationClasses()} ${className}`}\n style={getModalStyles()}\n onClick={(e) => e.stopPropagation()}\n >\n {(title || closable) && (\n <div\n className=\"flex items-center justify-between p-6 pb-4 border-b\"\n style={{ borderColor: 'var(--lm-border-default)' }}\n >\n {title && (\n <h3\n className={`font-semibold flex items-center gap-2 ${SIZE_HEADING_CLASSES[resolvedSize]}`}\n style={{ color: 'var(--lm-text-primary)' }}\n >\n <span style={{ color: 'var(--lm-text-secondary)' }}>\n {headerIcon || <WindowIcon />}\n </span>\n {title}\n </h3>\n )}\n {closable && (\n <LMButton\n variant=\"ghost\"\n size=\"xs\"\n onClick={handleCancel}\n leftIcon={closeIcon || <CloseIcon />}\n className=\"w-8 h-8 p-0\"\n aria-label=\"Close dialog\"\n title=\"Close\"\n style={{\n borderRadius: '0.5rem',\n backgroundColor: 'var(--lm-bg-paper)',\n borderColor: 'var(--lm-border-default)',\n color: 'var(--lm-text-secondary)',\n }}\n />\n )}\n </div>\n )}\n\n <div className=\"p-6\">{children}</div>\n\n {footer !== undefined\n ? footer\n : showOk || showCancel\n ? defaultFooter\n : null}\n </div>\n </div>\n )\n\n return createPortal(modalContent, document.body)\n}\n\nexport default memo(LMModal)\n"],"names":[],"mappings":"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"}
@@ -1,8 +1,10 @@
1
1
  "use strict";
2
2
  const jsxRuntime = require("react/jsx-runtime");
3
3
  const React = require("react");
4
+ const cn = require("./cn-I2jp-M-K.cjs");
4
5
  const componentSizes = require("./componentSizes-DUTZ7uEM.cjs");
5
- const LMNumberInput = ({
6
+ const ErrorMessage = require("./ErrorMessage-CbE7emgD.cjs");
7
+ const LMNumberInput = React.forwardRef(({
6
8
  value,
7
9
  onChange,
8
10
  error = false,
@@ -19,12 +21,17 @@ const LMNumberInput = ({
19
21
  showControls = true,
20
22
  prefix,
21
23
  suffix
22
- }) => {
24
+ }, ref) => {
23
25
  const [inputValue, setInputValue] = React.useState(
24
26
  value !== null && value !== void 0 ? String(value) : ""
25
27
  );
26
28
  const [isFocused, setIsFocused] = React.useState(false);
27
29
  const inputRef = React.useRef(null);
30
+ const setRefs = React.useCallback((node) => {
31
+ inputRef.current = node;
32
+ if (typeof ref === "function") ref(node);
33
+ else if (ref) ref.current = node;
34
+ }, [ref]);
28
35
  const errId = `lm-ni-err-${React.useId()}`;
29
36
  const formatNumber = React.useCallback(
30
37
  (num) => {
@@ -41,19 +48,22 @@ const LMNumberInput = ({
41
48
  setInputValue(formatNumber(value));
42
49
  }
43
50
  }, [value, isFocused, formatNumber]);
44
- const baseClassName = `
45
- w-full ${componentSizes.SIZE_INPUT_CONFIG[size].padding} ${componentSizes.SIZE_INPUT_CONFIG[size].height} ${componentSizes.SIZE_INPUT_CONFIG[size].fontSize}
46
- backdrop-blur-md border rounded-2xl
47
- focus:ring-2 focus:outline-none transition-all duration-300
48
- shadow-sm
49
- ${showControls ? "pr-10" : ""}
50
- ${prefix ? "pl-10" : ""}
51
- ${suffix ? "pr-10" : ""}
52
- ${className}
53
- [&::-webkit-outer-spin-button]:appearance-none
54
- [&::-webkit-inner-spin-button]:appearance-none
55
- [-moz-appearance:textfield]
56
- `.trim().replace(/\s+/g, " ");
51
+ const baseClassName = cn.cn(
52
+ "w-full",
53
+ componentSizes.SIZE_INPUT_CONFIG[size].padding,
54
+ componentSizes.SIZE_INPUT_CONFIG[size].height,
55
+ componentSizes.SIZE_INPUT_CONFIG[size].fontSize,
56
+ "backdrop-blur-md border rounded-2xl",
57
+ "focus:ring-2 focus:outline-none transition-all duration-300",
58
+ "shadow-sm",
59
+ showControls && "pr-10",
60
+ prefix && "pl-10",
61
+ suffix && "pr-10",
62
+ className,
63
+ "[&::-webkit-outer-spin-button]:appearance-none",
64
+ "[&::-webkit-inner-spin-button]:appearance-none",
65
+ "[-moz-appearance:textfield]"
66
+ );
57
67
  const getNumberInputStyles = () => {
58
68
  const base = {
59
69
  backgroundColor: "var(--lm-bg-elevated)",
@@ -186,7 +196,7 @@ const LMNumberInput = ({
186
196
  /* @__PURE__ */ jsxRuntime.jsx(
187
197
  "input",
188
198
  {
189
- ref: inputRef,
199
+ ref: setRefs,
190
200
  type: "number",
191
201
  name,
192
202
  value: inputValue,
@@ -267,28 +277,9 @@ const LMNumberInput = ({
267
277
  )
268
278
  ] })
269
279
  ] }),
270
- errorMessage && /* @__PURE__ */ jsxRuntime.jsxs(
271
- "p",
272
- {
273
- id: errId,
274
- className: "text-xs flex items-center gap-1",
275
- style: { color: "var(--lm-error-500)" },
276
- role: "alert",
277
- "aria-live": "polite",
278
- children: [
279
- /* @__PURE__ */ jsxRuntime.jsx("svg", { className: "w-3 h-3", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ jsxRuntime.jsx(
280
- "path",
281
- {
282
- fillRule: "evenodd",
283
- d: "M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z",
284
- clipRule: "evenodd"
285
- }
286
- ) }),
287
- errorMessage
288
- ]
289
- }
290
- )
280
+ errorMessage && /* @__PURE__ */ jsxRuntime.jsx(ErrorMessage.ErrorMessage, { message: errorMessage, id: errId })
291
281
  ] });
292
- };
282
+ });
283
+ LMNumberInput.displayName = "LMNumberInput";
293
284
  exports.LMNumberInput = LMNumberInput;
294
- //# sourceMappingURL=LMNumberInput-B1tU7T_W.cjs.map
285
+ //# sourceMappingURL=LMNumberInput-DQaLVoud.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LMNumberInput-DQaLVoud.cjs","sources":["../src/components/Form/LMNumberInput/LMNumberInput.tsx"],"sourcesContent":["import React, {\n useState,\n useRef,\n useEffect,\n useMemo,\n useCallback,\n useId,\n} from 'react'\nimport { cn } from '../../../utils/cn'\nimport { SIZE_INPUT_CONFIG } from '../../../utils/componentSizes'\nimport type { ComponentSize } from '../../../utils/componentSizes'\nimport { ErrorMessage } from '../../_internal/ErrorMessage'\n\nexport interface LMNumberInputProps {\n /** Current value (controlled) */\n value?: number | null\n /** Change callback */\n onChange?: (value: number | null) => void\n /** Error state */\n error?: boolean\n /** Error message */\n errorMessage?: string\n /** Placeholder */\n placeholder?: string\n /** Disabled state */\n disabled?: boolean\n /** Class name */\n className?: string\n /** Form field name */\n name?: string\n /** Size */\n size?: ComponentSize\n /** Minimum value */\n min?: number\n /** Maximum value */\n max?: number\n /** Step */\n step?: number\n /** Decimal precision */\n precision?: number\n /** Show increment/decrement controls */\n showControls?: boolean\n /** Prefix text */\n prefix?: string\n /** Suffix text */\n suffix?: string\n}\n\nconst LMNumberInput = React.forwardRef<HTMLInputElement, LMNumberInputProps>(({\n value,\n onChange,\n error = false,\n errorMessage,\n placeholder = 'Enter number...',\n disabled = false,\n className = '',\n name,\n size = 'md',\n min,\n max,\n step = 1,\n precision = 0,\n showControls = true,\n prefix,\n suffix,\n}, ref) => {\n const [inputValue, setInputValue] = useState<string>(\n value !== null && value !== undefined ? String(value) : ''\n )\n const [isFocused, setIsFocused] = useState(false)\n const inputRef = useRef<HTMLInputElement | null>(null)\n const setRefs = useCallback((node: HTMLInputElement | null) => {\n inputRef.current = node\n if (typeof ref === 'function') ref(node)\n else if (ref) (ref as { current: HTMLInputElement | null }).current = node\n }, [ref])\n const errId = `lm-ni-err-${useId()}`\n\n const formatNumber = useCallback(\n (num: number): string => {\n if (!Number.isFinite(num)) return ''\n if (precision <= 0) return String(Math.round(num))\n return num.toFixed(precision)\n },\n [precision]\n )\n\n useEffect(() => {\n if (value === undefined || value === null) {\n setInputValue('')\n } else if (!isFocused) {\n setInputValue(formatNumber(value))\n }\n }, [value, isFocused, formatNumber])\n\n const baseClassName = cn(\n 'w-full',\n SIZE_INPUT_CONFIG[size].padding,\n SIZE_INPUT_CONFIG[size].height,\n SIZE_INPUT_CONFIG[size].fontSize,\n 'backdrop-blur-md border rounded-2xl',\n 'focus:ring-2 focus:outline-none transition-all duration-300',\n 'shadow-sm',\n showControls && 'pr-10',\n prefix && 'pl-10',\n suffix && 'pr-10',\n className,\n '[&::-webkit-outer-spin-button]:appearance-none',\n '[&::-webkit-inner-spin-button]:appearance-none',\n '[-moz-appearance:textfield]'\n )\n\n const getNumberInputStyles = () => {\n const base = {\n backgroundColor: 'var(--lm-bg-elevated)',\n color: 'var(--lm-text-primary)',\n borderColor: error\n ? 'var(--lm-error-300)'\n : isFocused\n ? 'var(--lm-primary-400)'\n : 'var(--lm-border-default)',\n boxShadow: 'var(--lm-shadow-sm)',\n } as React.CSSProperties\n\n return {\n ...base,\n '--tw-ring-color': error\n ? 'var(--lm-error-400)'\n : 'var(--lm-primary-400)',\n '--tw-ring-opacity': '0.3',\n }\n }\n\n const getDisabledStyles = () =>\n disabled\n ? {\n backgroundColor: 'var(--lm-bg-paper)',\n color: 'var(--lm-text-disabled)',\n cursor: 'not-allowed',\n opacity: 0.6,\n }\n : {}\n\n const getIconStyles = () => {\n if (error) return { color: 'var(--lm-error-400)' }\n if (isFocused) return { color: 'var(--lm-primary-500)' }\n return { color: 'var(--lm-text-secondary)' }\n }\n\n const getControlButtonStyles = () => ({\n backgroundColor: 'var(--lm-bg-paper)',\n color: 'var(--lm-text-secondary)',\n borderColor: 'var(--lm-border-light)',\n })\n\n const getHoverControlButtonStyles = () => ({\n backgroundColor: 'var(--lm-bg-elevated)',\n color: 'var(--lm-text-primary)',\n })\n\n const parseNumber = (str: string): number | null => {\n const n = parseFloat(str)\n return Number.isNaN(n) ? null : n\n }\n\n const clamp = (num: number): number => {\n let v = num\n if (min !== undefined) v = Math.max(v, min)\n if (max !== undefined) v = Math.min(v, max)\n return v\n }\n\n const stepFrom = useMemo(() => min ?? 0, [min])\n const alignToStep = (num: number) => {\n const offset = num - stepFrom\n const k = Math.round(offset / step)\n const next = stepFrom + k * step\n return Number(next.toFixed(Math.max(precision, 12)))\n }\n\n const handleInputChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n const val = event.target.value\n setInputValue(val)\n\n if (val.trim() === '') {\n onChange?.(null)\n return\n }\n\n const num = parseNumber(val)\n if (num === null) return\n\n const clamped = clamp(num)\n if (clamped !== num) return\n onChange?.(num)\n }\n\n const changeByStep = (delta: number) => {\n if (disabled) return\n\n const current = parseNumber(inputValue)\n const base = current ?? min ?? 0\n const raw = base + delta * step\n const clamped = clamp(raw)\n const aligned = alignToStep(clamped)\n\n setInputValue(formatNumber(aligned))\n onChange?.(aligned)\n }\n\n const handleIncrement = () => changeByStep(+1)\n const handleDecrement = () => changeByStep(-1)\n\n const handleKeyDown = (event: React.KeyboardEvent) => {\n if (event.key === 'ArrowUp') {\n event.preventDefault()\n handleIncrement()\n } else if (event.key === 'ArrowDown') {\n event.preventDefault()\n handleDecrement()\n }\n }\n\n const handleFocus = () => setIsFocused(true)\n const handleBlur = () => {\n setIsFocused(false)\n\n if (inputValue.trim() === '') {\n setInputValue('')\n if (value !== null) onChange?.(null)\n return\n }\n\n const num = parseNumber(inputValue)\n if (num === null) {\n if (typeof value === 'number') {\n setInputValue(formatNumber(clamp(value)))\n } else {\n setInputValue('')\n if (value !== null) onChange?.(null)\n }\n return\n }\n let v = clamp(num)\n v = alignToStep(v)\n const formatted = formatNumber(v)\n setInputValue(formatted)\n if (v !== value) onChange?.(v)\n }\n\n const handleWheel: React.WheelEventHandler<HTMLInputElement> = (e) => {\n if (document.activeElement === inputRef.current) {\n e.preventDefault()\n }\n }\n\n const currentNum = parseNumber(inputValue)\n const incDisabled = useMemo(() => {\n if (disabled) return true\n const base = currentNum ?? min ?? 0\n return max !== undefined && base >= max\n }, [disabled, currentNum, min, max])\n\n const decDisabled = useMemo(() => {\n if (disabled) return true\n const base = currentNum ?? min ?? 0\n return min !== undefined && base <= min\n }, [disabled, currentNum, min])\n\n const ChevronUp = () => (\n <svg className=\"w-3 h-3\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M5 15l7-7 7 7\" />\n </svg>\n )\n\n const ChevronDown = () => (\n <svg className=\"w-3 h-3\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M19 9l-7 7-7-7\" />\n </svg>\n )\n\n return (\n <div className=\"space-y-2\">\n <div className=\"relative group\">\n {prefix && (\n <div className=\"absolute inset-y-0 left-0 pl-4 flex items-center pointer-events-none z-10\">\n <span className=\"text-sm font-medium\" style={getIconStyles()}>\n {prefix}\n </span>\n </div>\n )}\n\n <input\n ref={setRefs}\n type=\"number\"\n name={name}\n value={inputValue}\n placeholder={placeholder}\n disabled={disabled}\n min={min}\n max={max}\n step={step}\n inputMode=\"decimal\"\n className={baseClassName}\n style={{ ...getNumberInputStyles(), ...getDisabledStyles() } as React.CSSProperties}\n aria-invalid={error || undefined}\n aria-describedby={errorMessage ? errId : undefined}\n onChange={handleInputChange}\n onKeyDown={handleKeyDown}\n onFocus={handleFocus}\n onBlur={handleBlur}\n onWheel={handleWheel}\n onMouseEnter={(e) => {\n if (!disabled && !error && !isFocused) {\n e.currentTarget.style.borderColor = 'var(--lm-border-strong)'\n }\n }}\n onMouseLeave={(e) => {\n if (!disabled && !error && !isFocused) {\n e.currentTarget.style.borderColor = 'var(--lm-border-default)'\n }\n }}\n />\n\n {suffix && (\n <div\n className={`absolute inset-y-0 flex items-center pointer-events-none z-10 ${\n showControls ? 'right-10' : 'right-4'\n }`}\n >\n <span className=\"text-sm font-medium\" style={getIconStyles()}>\n {suffix}\n </span>\n </div>\n )}\n\n {showControls && (\n <div className=\"absolute inset-y-0 right-0 flex flex-col w-8\">\n <button\n type=\"button\"\n aria-label=\"Increment\"\n onClick={handleIncrement}\n disabled={incDisabled}\n className=\"flex-1 px-1 border-l border-b rounded-tr-2xl transition-colors duration-200 flex items-center justify-center\"\n style={getControlButtonStyles()}\n onMouseEnter={(e) => {\n if (!incDisabled)\n Object.assign(e.currentTarget.style, getHoverControlButtonStyles())\n }}\n onMouseLeave={(e) => {\n if (!incDisabled)\n Object.assign(e.currentTarget.style, getControlButtonStyles())\n }}\n >\n <ChevronUp />\n </button>\n <button\n type=\"button\"\n aria-label=\"Decrement\"\n onClick={handleDecrement}\n disabled={decDisabled}\n className=\"flex-1 px-1 border-l rounded-br-2xl transition-colors duration-200 flex items-center justify-center\"\n style={getControlButtonStyles()}\n onMouseEnter={(e) => {\n if (!decDisabled)\n Object.assign(e.currentTarget.style, getHoverControlButtonStyles())\n }}\n onMouseLeave={(e) => {\n if (!decDisabled)\n Object.assign(e.currentTarget.style, getControlButtonStyles())\n }}\n >\n <ChevronDown />\n </button>\n </div>\n )}\n </div>\n\n {errorMessage && <ErrorMessage message={errorMessage} id={errId} />}\n </div>\n )\n})\n\nLMNumberInput.displayName = 'LMNumberInput'\n\nexport default LMNumberInput\n"],"names":["useState","useRef","useCallback","useId","useEffect","cn","SIZE_INPUT_CONFIG","useMemo","jsx","jsxs","ErrorMessage"],"mappings":"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"}
@@ -1,7 +1,9 @@
1
1
  import { jsxs, jsx } from "react/jsx-runtime";
2
- import { useState, useRef, useId, useCallback, useEffect, useMemo } from "react";
2
+ import React, { useState, useRef, useCallback, useId, useEffect, useMemo } from "react";
3
+ import { c as cn } from "./cn-wDEkOmcn.js";
3
4
  import { a as SIZE_INPUT_CONFIG } from "./componentSizes-CdWNL526.js";
4
- const LMNumberInput = ({
5
+ import { E as ErrorMessage } from "./ErrorMessage-Dt4cJ-sy.js";
6
+ const LMNumberInput = React.forwardRef(({
5
7
  value,
6
8
  onChange,
7
9
  error = false,
@@ -18,12 +20,17 @@ const LMNumberInput = ({
18
20
  showControls = true,
19
21
  prefix,
20
22
  suffix
21
- }) => {
23
+ }, ref) => {
22
24
  const [inputValue, setInputValue] = useState(
23
25
  value !== null && value !== void 0 ? String(value) : ""
24
26
  );
25
27
  const [isFocused, setIsFocused] = useState(false);
26
28
  const inputRef = useRef(null);
29
+ const setRefs = useCallback((node) => {
30
+ inputRef.current = node;
31
+ if (typeof ref === "function") ref(node);
32
+ else if (ref) ref.current = node;
33
+ }, [ref]);
27
34
  const errId = `lm-ni-err-${useId()}`;
28
35
  const formatNumber = useCallback(
29
36
  (num) => {
@@ -40,19 +47,22 @@ const LMNumberInput = ({
40
47
  setInputValue(formatNumber(value));
41
48
  }
42
49
  }, [value, isFocused, formatNumber]);
43
- const baseClassName = `
44
- w-full ${SIZE_INPUT_CONFIG[size].padding} ${SIZE_INPUT_CONFIG[size].height} ${SIZE_INPUT_CONFIG[size].fontSize}
45
- backdrop-blur-md border rounded-2xl
46
- focus:ring-2 focus:outline-none transition-all duration-300
47
- shadow-sm
48
- ${showControls ? "pr-10" : ""}
49
- ${prefix ? "pl-10" : ""}
50
- ${suffix ? "pr-10" : ""}
51
- ${className}
52
- [&::-webkit-outer-spin-button]:appearance-none
53
- [&::-webkit-inner-spin-button]:appearance-none
54
- [-moz-appearance:textfield]
55
- `.trim().replace(/\s+/g, " ");
50
+ const baseClassName = cn(
51
+ "w-full",
52
+ SIZE_INPUT_CONFIG[size].padding,
53
+ SIZE_INPUT_CONFIG[size].height,
54
+ SIZE_INPUT_CONFIG[size].fontSize,
55
+ "backdrop-blur-md border rounded-2xl",
56
+ "focus:ring-2 focus:outline-none transition-all duration-300",
57
+ "shadow-sm",
58
+ showControls && "pr-10",
59
+ prefix && "pl-10",
60
+ suffix && "pr-10",
61
+ className,
62
+ "[&::-webkit-outer-spin-button]:appearance-none",
63
+ "[&::-webkit-inner-spin-button]:appearance-none",
64
+ "[-moz-appearance:textfield]"
65
+ );
56
66
  const getNumberInputStyles = () => {
57
67
  const base = {
58
68
  backgroundColor: "var(--lm-bg-elevated)",
@@ -185,7 +195,7 @@ const LMNumberInput = ({
185
195
  /* @__PURE__ */ jsx(
186
196
  "input",
187
197
  {
188
- ref: inputRef,
198
+ ref: setRefs,
189
199
  type: "number",
190
200
  name,
191
201
  value: inputValue,
@@ -266,30 +276,11 @@ const LMNumberInput = ({
266
276
  )
267
277
  ] })
268
278
  ] }),
269
- errorMessage && /* @__PURE__ */ jsxs(
270
- "p",
271
- {
272
- id: errId,
273
- className: "text-xs flex items-center gap-1",
274
- style: { color: "var(--lm-error-500)" },
275
- role: "alert",
276
- "aria-live": "polite",
277
- children: [
278
- /* @__PURE__ */ jsx("svg", { className: "w-3 h-3", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ jsx(
279
- "path",
280
- {
281
- fillRule: "evenodd",
282
- d: "M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z",
283
- clipRule: "evenodd"
284
- }
285
- ) }),
286
- errorMessage
287
- ]
288
- }
289
- )
279
+ errorMessage && /* @__PURE__ */ jsx(ErrorMessage, { message: errorMessage, id: errId })
290
280
  ] });
291
- };
281
+ });
282
+ LMNumberInput.displayName = "LMNumberInput";
292
283
  export {
293
284
  LMNumberInput as L
294
285
  };
295
- //# sourceMappingURL=LMNumberInput-BI5_OEx4.js.map
286
+ //# sourceMappingURL=LMNumberInput-gnRvWRly.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LMNumberInput-gnRvWRly.js","sources":["../src/components/Form/LMNumberInput/LMNumberInput.tsx"],"sourcesContent":["import React, {\n useState,\n useRef,\n useEffect,\n useMemo,\n useCallback,\n useId,\n} from 'react'\nimport { cn } from '../../../utils/cn'\nimport { SIZE_INPUT_CONFIG } from '../../../utils/componentSizes'\nimport type { ComponentSize } from '../../../utils/componentSizes'\nimport { ErrorMessage } from '../../_internal/ErrorMessage'\n\nexport interface LMNumberInputProps {\n /** Current value (controlled) */\n value?: number | null\n /** Change callback */\n onChange?: (value: number | null) => void\n /** Error state */\n error?: boolean\n /** Error message */\n errorMessage?: string\n /** Placeholder */\n placeholder?: string\n /** Disabled state */\n disabled?: boolean\n /** Class name */\n className?: string\n /** Form field name */\n name?: string\n /** Size */\n size?: ComponentSize\n /** Minimum value */\n min?: number\n /** Maximum value */\n max?: number\n /** Step */\n step?: number\n /** Decimal precision */\n precision?: number\n /** Show increment/decrement controls */\n showControls?: boolean\n /** Prefix text */\n prefix?: string\n /** Suffix text */\n suffix?: string\n}\n\nconst LMNumberInput = React.forwardRef<HTMLInputElement, LMNumberInputProps>(({\n value,\n onChange,\n error = false,\n errorMessage,\n placeholder = 'Enter number...',\n disabled = false,\n className = '',\n name,\n size = 'md',\n min,\n max,\n step = 1,\n precision = 0,\n showControls = true,\n prefix,\n suffix,\n}, ref) => {\n const [inputValue, setInputValue] = useState<string>(\n value !== null && value !== undefined ? String(value) : ''\n )\n const [isFocused, setIsFocused] = useState(false)\n const inputRef = useRef<HTMLInputElement | null>(null)\n const setRefs = useCallback((node: HTMLInputElement | null) => {\n inputRef.current = node\n if (typeof ref === 'function') ref(node)\n else if (ref) (ref as { current: HTMLInputElement | null }).current = node\n }, [ref])\n const errId = `lm-ni-err-${useId()}`\n\n const formatNumber = useCallback(\n (num: number): string => {\n if (!Number.isFinite(num)) return ''\n if (precision <= 0) return String(Math.round(num))\n return num.toFixed(precision)\n },\n [precision]\n )\n\n useEffect(() => {\n if (value === undefined || value === null) {\n setInputValue('')\n } else if (!isFocused) {\n setInputValue(formatNumber(value))\n }\n }, [value, isFocused, formatNumber])\n\n const baseClassName = cn(\n 'w-full',\n SIZE_INPUT_CONFIG[size].padding,\n SIZE_INPUT_CONFIG[size].height,\n SIZE_INPUT_CONFIG[size].fontSize,\n 'backdrop-blur-md border rounded-2xl',\n 'focus:ring-2 focus:outline-none transition-all duration-300',\n 'shadow-sm',\n showControls && 'pr-10',\n prefix && 'pl-10',\n suffix && 'pr-10',\n className,\n '[&::-webkit-outer-spin-button]:appearance-none',\n '[&::-webkit-inner-spin-button]:appearance-none',\n '[-moz-appearance:textfield]'\n )\n\n const getNumberInputStyles = () => {\n const base = {\n backgroundColor: 'var(--lm-bg-elevated)',\n color: 'var(--lm-text-primary)',\n borderColor: error\n ? 'var(--lm-error-300)'\n : isFocused\n ? 'var(--lm-primary-400)'\n : 'var(--lm-border-default)',\n boxShadow: 'var(--lm-shadow-sm)',\n } as React.CSSProperties\n\n return {\n ...base,\n '--tw-ring-color': error\n ? 'var(--lm-error-400)'\n : 'var(--lm-primary-400)',\n '--tw-ring-opacity': '0.3',\n }\n }\n\n const getDisabledStyles = () =>\n disabled\n ? {\n backgroundColor: 'var(--lm-bg-paper)',\n color: 'var(--lm-text-disabled)',\n cursor: 'not-allowed',\n opacity: 0.6,\n }\n : {}\n\n const getIconStyles = () => {\n if (error) return { color: 'var(--lm-error-400)' }\n if (isFocused) return { color: 'var(--lm-primary-500)' }\n return { color: 'var(--lm-text-secondary)' }\n }\n\n const getControlButtonStyles = () => ({\n backgroundColor: 'var(--lm-bg-paper)',\n color: 'var(--lm-text-secondary)',\n borderColor: 'var(--lm-border-light)',\n })\n\n const getHoverControlButtonStyles = () => ({\n backgroundColor: 'var(--lm-bg-elevated)',\n color: 'var(--lm-text-primary)',\n })\n\n const parseNumber = (str: string): number | null => {\n const n = parseFloat(str)\n return Number.isNaN(n) ? null : n\n }\n\n const clamp = (num: number): number => {\n let v = num\n if (min !== undefined) v = Math.max(v, min)\n if (max !== undefined) v = Math.min(v, max)\n return v\n }\n\n const stepFrom = useMemo(() => min ?? 0, [min])\n const alignToStep = (num: number) => {\n const offset = num - stepFrom\n const k = Math.round(offset / step)\n const next = stepFrom + k * step\n return Number(next.toFixed(Math.max(precision, 12)))\n }\n\n const handleInputChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n const val = event.target.value\n setInputValue(val)\n\n if (val.trim() === '') {\n onChange?.(null)\n return\n }\n\n const num = parseNumber(val)\n if (num === null) return\n\n const clamped = clamp(num)\n if (clamped !== num) return\n onChange?.(num)\n }\n\n const changeByStep = (delta: number) => {\n if (disabled) return\n\n const current = parseNumber(inputValue)\n const base = current ?? min ?? 0\n const raw = base + delta * step\n const clamped = clamp(raw)\n const aligned = alignToStep(clamped)\n\n setInputValue(formatNumber(aligned))\n onChange?.(aligned)\n }\n\n const handleIncrement = () => changeByStep(+1)\n const handleDecrement = () => changeByStep(-1)\n\n const handleKeyDown = (event: React.KeyboardEvent) => {\n if (event.key === 'ArrowUp') {\n event.preventDefault()\n handleIncrement()\n } else if (event.key === 'ArrowDown') {\n event.preventDefault()\n handleDecrement()\n }\n }\n\n const handleFocus = () => setIsFocused(true)\n const handleBlur = () => {\n setIsFocused(false)\n\n if (inputValue.trim() === '') {\n setInputValue('')\n if (value !== null) onChange?.(null)\n return\n }\n\n const num = parseNumber(inputValue)\n if (num === null) {\n if (typeof value === 'number') {\n setInputValue(formatNumber(clamp(value)))\n } else {\n setInputValue('')\n if (value !== null) onChange?.(null)\n }\n return\n }\n let v = clamp(num)\n v = alignToStep(v)\n const formatted = formatNumber(v)\n setInputValue(formatted)\n if (v !== value) onChange?.(v)\n }\n\n const handleWheel: React.WheelEventHandler<HTMLInputElement> = (e) => {\n if (document.activeElement === inputRef.current) {\n e.preventDefault()\n }\n }\n\n const currentNum = parseNumber(inputValue)\n const incDisabled = useMemo(() => {\n if (disabled) return true\n const base = currentNum ?? min ?? 0\n return max !== undefined && base >= max\n }, [disabled, currentNum, min, max])\n\n const decDisabled = useMemo(() => {\n if (disabled) return true\n const base = currentNum ?? min ?? 0\n return min !== undefined && base <= min\n }, [disabled, currentNum, min])\n\n const ChevronUp = () => (\n <svg className=\"w-3 h-3\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M5 15l7-7 7 7\" />\n </svg>\n )\n\n const ChevronDown = () => (\n <svg className=\"w-3 h-3\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M19 9l-7 7-7-7\" />\n </svg>\n )\n\n return (\n <div className=\"space-y-2\">\n <div className=\"relative group\">\n {prefix && (\n <div className=\"absolute inset-y-0 left-0 pl-4 flex items-center pointer-events-none z-10\">\n <span className=\"text-sm font-medium\" style={getIconStyles()}>\n {prefix}\n </span>\n </div>\n )}\n\n <input\n ref={setRefs}\n type=\"number\"\n name={name}\n value={inputValue}\n placeholder={placeholder}\n disabled={disabled}\n min={min}\n max={max}\n step={step}\n inputMode=\"decimal\"\n className={baseClassName}\n style={{ ...getNumberInputStyles(), ...getDisabledStyles() } as React.CSSProperties}\n aria-invalid={error || undefined}\n aria-describedby={errorMessage ? errId : undefined}\n onChange={handleInputChange}\n onKeyDown={handleKeyDown}\n onFocus={handleFocus}\n onBlur={handleBlur}\n onWheel={handleWheel}\n onMouseEnter={(e) => {\n if (!disabled && !error && !isFocused) {\n e.currentTarget.style.borderColor = 'var(--lm-border-strong)'\n }\n }}\n onMouseLeave={(e) => {\n if (!disabled && !error && !isFocused) {\n e.currentTarget.style.borderColor = 'var(--lm-border-default)'\n }\n }}\n />\n\n {suffix && (\n <div\n className={`absolute inset-y-0 flex items-center pointer-events-none z-10 ${\n showControls ? 'right-10' : 'right-4'\n }`}\n >\n <span className=\"text-sm font-medium\" style={getIconStyles()}>\n {suffix}\n </span>\n </div>\n )}\n\n {showControls && (\n <div className=\"absolute inset-y-0 right-0 flex flex-col w-8\">\n <button\n type=\"button\"\n aria-label=\"Increment\"\n onClick={handleIncrement}\n disabled={incDisabled}\n className=\"flex-1 px-1 border-l border-b rounded-tr-2xl transition-colors duration-200 flex items-center justify-center\"\n style={getControlButtonStyles()}\n onMouseEnter={(e) => {\n if (!incDisabled)\n Object.assign(e.currentTarget.style, getHoverControlButtonStyles())\n }}\n onMouseLeave={(e) => {\n if (!incDisabled)\n Object.assign(e.currentTarget.style, getControlButtonStyles())\n }}\n >\n <ChevronUp />\n </button>\n <button\n type=\"button\"\n aria-label=\"Decrement\"\n onClick={handleDecrement}\n disabled={decDisabled}\n className=\"flex-1 px-1 border-l rounded-br-2xl transition-colors duration-200 flex items-center justify-center\"\n style={getControlButtonStyles()}\n onMouseEnter={(e) => {\n if (!decDisabled)\n Object.assign(e.currentTarget.style, getHoverControlButtonStyles())\n }}\n onMouseLeave={(e) => {\n if (!decDisabled)\n Object.assign(e.currentTarget.style, getControlButtonStyles())\n }}\n >\n <ChevronDown />\n </button>\n </div>\n )}\n </div>\n\n {errorMessage && <ErrorMessage message={errorMessage} id={errId} />}\n </div>\n )\n})\n\nLMNumberInput.displayName = 'LMNumberInput'\n\nexport default LMNumberInput\n"],"names":[],"mappings":"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"}
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
2
  const jsxRuntime = require("react/jsx-runtime");
3
3
  const React = require("react");
4
+ const cn = require("./cn-I2jp-M-K.cjs");
4
5
  const componentSizes = require("./componentSizes-DUTZ7uEM.cjs");
6
+ const ErrorMessage = require("./ErrorMessage-CbE7emgD.cjs");
5
7
  const sizeConfig = {
6
8
  xs: {
7
9
  container: "p-2 gap-2",
@@ -91,12 +93,13 @@ const LMRadio = ({
91
93
  return { color: "var(--lm-text-primary)", cursor: "pointer" };
92
94
  };
93
95
  const getDescriptionStyles = () => error ? { color: "var(--lm-error-600)" } : { color: "var(--lm-text-secondary)" };
94
- const radioClassName = `
95
- ${radioSizeClass} border-2 rounded-full
96
- focus:ring-2 focus:ring-offset-0
97
- transition-all duration-200
98
- ${className}
99
- `.trim().replace(/\s+/g, " ");
96
+ const radioClassName = cn.cn(
97
+ radioSizeClass,
98
+ "border-2 rounded-full",
99
+ "focus:ring-2 focus:ring-offset-0",
100
+ "transition-all duration-200",
101
+ className
102
+ );
100
103
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
101
104
  /* @__PURE__ */ jsxRuntime.jsxs(
102
105
  "div",
@@ -153,37 +156,8 @@ const LMRadio = ({
153
156
  ]
154
157
  }
155
158
  ),
156
- errorMessage && /* @__PURE__ */ jsxRuntime.jsxs(
157
- "p",
158
- {
159
- id: errId,
160
- className: `${currentSize.errorMessage} flex items-center gap-1`,
161
- style: { color: "var(--lm-error-500)" },
162
- role: "alert",
163
- "aria-live": "polite",
164
- children: [
165
- /* @__PURE__ */ jsxRuntime.jsx(
166
- "svg",
167
- {
168
- className: "w-3 h-3",
169
- fill: "currentColor",
170
- viewBox: "0 0 20 20",
171
- "aria-hidden": "true",
172
- children: /* @__PURE__ */ jsxRuntime.jsx(
173
- "path",
174
- {
175
- fillRule: "evenodd",
176
- d: "M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z",
177
- clipRule: "evenodd"
178
- }
179
- )
180
- }
181
- ),
182
- errorMessage
183
- ]
184
- }
185
- )
159
+ errorMessage && /* @__PURE__ */ jsxRuntime.jsx(ErrorMessage.ErrorMessage, { message: errorMessage })
186
160
  ] });
187
161
  };
188
162
  exports.LMRadio = LMRadio;
189
- //# sourceMappingURL=LMRadio-CHn6nFSy.cjs.map
163
+ //# sourceMappingURL=LMRadio-BVBwm1rk.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LMRadio-BVBwm1rk.cjs","sources":["../src/components/Form/LMRadio/LMRadio.tsx"],"sourcesContent":["import React, { useId } from 'react'\nimport { cn } from '../../../utils/cn'\nimport { SIZE_ICON_CONFIG } from '../../../utils/componentSizes'\nimport type { ComponentSize } from '../../../utils/componentSizes'\nimport { ErrorMessage } from '../../_internal/ErrorMessage'\n\nexport interface LMRadioProps\n extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'type' | 'size'> {\n /** Label text */\n label: string\n /** Description text */\n description?: string\n /** Error state */\n error?: boolean\n /** Error message */\n errorMessage?: string\n /** Size */\n size?: ComponentSize\n}\n\nconst sizeConfig = {\n xs: {\n container: 'p-2 gap-2',\n label: 'text-xs',\n description: 'text-xs mt-0.5',\n errorMessage: 'text-xs',\n },\n sm: {\n container: 'p-3 gap-2.5',\n label: 'text-sm',\n description: 'text-xs mt-1',\n errorMessage: 'text-xs',\n },\n md: {\n container: 'p-4 gap-3',\n label: 'text-base',\n description: 'text-sm mt-1',\n errorMessage: 'text-xs',\n },\n lg: {\n container: 'p-5 gap-4',\n label: 'text-lg',\n description: 'text-base mt-1.5',\n errorMessage: 'text-sm',\n },\n xl: {\n container: 'p-6 gap-4',\n label: 'text-xl',\n description: 'text-lg mt-2',\n errorMessage: 'text-sm',\n },\n '2xl': {\n container: 'p-8 gap-5',\n label: 'text-2xl',\n description: 'text-xl mt-2.5',\n errorMessage: 'text-base',\n },\n}\n\nconst LMRadio: React.FC<LMRadioProps> = ({\n label,\n description,\n error = false,\n errorMessage,\n size = 'md',\n className = '',\n id,\n ...props\n}) => {\n const autoId = useId()\n const controlId = id ?? `lm-radio-${autoId}`\n const errId = `lm-radio-err-${autoId}`\n\n const currentSize = sizeConfig[size]\n const radioSizeClass = SIZE_ICON_CONFIG[size]\n\n const getRadioStyles = () => {\n const baseStyles = {\n backgroundColor: 'var(--lm-bg-elevated)',\n borderColor: error\n ? 'var(--lm-error-300)'\n : 'var(--lm-border-default)',\n color: 'var(--lm-primary-500)',\n } as React.CSSProperties\n\n return {\n ...baseStyles,\n '--tw-ring-color': error\n ? 'var(--lm-error-400)'\n : 'var(--lm-primary-400)',\n '--tw-ring-opacity': '0.3',\n }\n }\n\n const getDisabledStyles = () => {\n if (props.disabled) {\n return {\n backgroundColor: 'var(--lm-bg-paper)',\n borderColor: 'var(--lm-border-light)',\n color: 'var(--lm-text-disabled)',\n cursor: 'not-allowed',\n opacity: 0.6,\n } as React.CSSProperties\n }\n return {}\n }\n\n const getContainerStyles = () => {\n const base = { backgroundColor: 'var(--lm-bg-paper)' }\n return error ? { ...base, backgroundColor: 'var(--lm-error-50)' } : base\n }\n\n const getHoverContainerStyles = () =>\n error\n ? { backgroundColor: 'var(--lm-error-100)' }\n : { backgroundColor: 'var(--lm-bg-elevated)' }\n\n const getLabelStyles = () => {\n if (error) return { color: 'var(--lm-error-700)' }\n if (props.disabled)\n return { color: 'var(--lm-text-disabled)', cursor: 'not-allowed' }\n return { color: 'var(--lm-text-primary)', cursor: 'pointer' }\n }\n\n const getDescriptionStyles = () =>\n error\n ? { color: 'var(--lm-error-600)' }\n : { color: 'var(--lm-text-secondary)' }\n\n const radioClassName = cn(\n radioSizeClass,\n 'border-2 rounded-full',\n 'focus:ring-2 focus:ring-offset-0',\n 'transition-all duration-200',\n className\n )\n\n return (\n <div>\n <div\n className={`flex items-start ${currentSize.container} rounded-2xl transition-colors duration-200`}\n style={getContainerStyles()}\n onMouseEnter={(e) => {\n if (!props.disabled)\n Object.assign(e.currentTarget.style, getHoverContainerStyles())\n }}\n onMouseLeave={(e) => {\n if (!props.disabled)\n Object.assign(e.currentTarget.style, getContainerStyles())\n }}\n >\n <input\n type=\"radio\"\n id={controlId}\n {...props}\n className={radioClassName}\n aria-invalid={error || undefined}\n aria-describedby={errorMessage ? errId : undefined}\n style={{ ...getRadioStyles(), ...getDisabledStyles() } as React.CSSProperties}\n onFocus={(e) => {\n if (!props.disabled) {\n e.currentTarget.style.borderColor = error\n ? 'var(--lm-error-400)'\n : 'var(--lm-primary-400)'\n }\n props.onFocus?.(e)\n }}\n onBlur={(e) => {\n if (!props.disabled) {\n e.currentTarget.style.borderColor = error\n ? 'var(--lm-error-300)'\n : 'var(--lm-border-default)'\n }\n props.onBlur?.(e)\n }}\n />\n\n <div className=\"flex-1\">\n <label\n htmlFor={controlId}\n className={`${currentSize.label} font-medium transition-colors duration-200`}\n style={getLabelStyles()}\n >\n {label}\n </label>\n {description && (\n <p className={currentSize.description} style={getDescriptionStyles()}>\n {description}\n </p>\n )}\n </div>\n </div>\n\n {errorMessage && <ErrorMessage message={errorMessage} />}\n </div>\n )\n}\n\nexport default LMRadio\n"],"names":["useId","SIZE_ICON_CONFIG","cn","jsxs","jsx","ErrorMessage"],"mappings":"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"}
@@ -1,6 +1,8 @@
1
1
  import { jsxs, jsx } from "react/jsx-runtime";
2
2
  import { useId } from "react";
3
+ import { c as cn } from "./cn-wDEkOmcn.js";
3
4
  import { S as SIZE_ICON_CONFIG } from "./componentSizes-CdWNL526.js";
5
+ import { E as ErrorMessage } from "./ErrorMessage-Dt4cJ-sy.js";
4
6
  const sizeConfig = {
5
7
  xs: {
6
8
  container: "p-2 gap-2",
@@ -90,12 +92,13 @@ const LMRadio = ({
90
92
  return { color: "var(--lm-text-primary)", cursor: "pointer" };
91
93
  };
92
94
  const getDescriptionStyles = () => error ? { color: "var(--lm-error-600)" } : { color: "var(--lm-text-secondary)" };
93
- const radioClassName = `
94
- ${radioSizeClass} border-2 rounded-full
95
- focus:ring-2 focus:ring-offset-0
96
- transition-all duration-200
97
- ${className}
98
- `.trim().replace(/\s+/g, " ");
95
+ const radioClassName = cn(
96
+ radioSizeClass,
97
+ "border-2 rounded-full",
98
+ "focus:ring-2 focus:ring-offset-0",
99
+ "transition-all duration-200",
100
+ className
101
+ );
99
102
  return /* @__PURE__ */ jsxs("div", { children: [
100
103
  /* @__PURE__ */ jsxs(
101
104
  "div",
@@ -152,39 +155,10 @@ const LMRadio = ({
152
155
  ]
153
156
  }
154
157
  ),
155
- errorMessage && /* @__PURE__ */ jsxs(
156
- "p",
157
- {
158
- id: errId,
159
- className: `${currentSize.errorMessage} flex items-center gap-1`,
160
- style: { color: "var(--lm-error-500)" },
161
- role: "alert",
162
- "aria-live": "polite",
163
- children: [
164
- /* @__PURE__ */ jsx(
165
- "svg",
166
- {
167
- className: "w-3 h-3",
168
- fill: "currentColor",
169
- viewBox: "0 0 20 20",
170
- "aria-hidden": "true",
171
- children: /* @__PURE__ */ jsx(
172
- "path",
173
- {
174
- fillRule: "evenodd",
175
- d: "M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z",
176
- clipRule: "evenodd"
177
- }
178
- )
179
- }
180
- ),
181
- errorMessage
182
- ]
183
- }
184
- )
158
+ errorMessage && /* @__PURE__ */ jsx(ErrorMessage, { message: errorMessage })
185
159
  ] });
186
160
  };
187
161
  export {
188
162
  LMRadio as L
189
163
  };
190
- //# sourceMappingURL=LMRadio-UQLNgTMF.js.map
164
+ //# sourceMappingURL=LMRadio-C0ZL0hVK.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LMRadio-C0ZL0hVK.js","sources":["../src/components/Form/LMRadio/LMRadio.tsx"],"sourcesContent":["import React, { useId } from 'react'\nimport { cn } from '../../../utils/cn'\nimport { SIZE_ICON_CONFIG } from '../../../utils/componentSizes'\nimport type { ComponentSize } from '../../../utils/componentSizes'\nimport { ErrorMessage } from '../../_internal/ErrorMessage'\n\nexport interface LMRadioProps\n extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'type' | 'size'> {\n /** Label text */\n label: string\n /** Description text */\n description?: string\n /** Error state */\n error?: boolean\n /** Error message */\n errorMessage?: string\n /** Size */\n size?: ComponentSize\n}\n\nconst sizeConfig = {\n xs: {\n container: 'p-2 gap-2',\n label: 'text-xs',\n description: 'text-xs mt-0.5',\n errorMessage: 'text-xs',\n },\n sm: {\n container: 'p-3 gap-2.5',\n label: 'text-sm',\n description: 'text-xs mt-1',\n errorMessage: 'text-xs',\n },\n md: {\n container: 'p-4 gap-3',\n label: 'text-base',\n description: 'text-sm mt-1',\n errorMessage: 'text-xs',\n },\n lg: {\n container: 'p-5 gap-4',\n label: 'text-lg',\n description: 'text-base mt-1.5',\n errorMessage: 'text-sm',\n },\n xl: {\n container: 'p-6 gap-4',\n label: 'text-xl',\n description: 'text-lg mt-2',\n errorMessage: 'text-sm',\n },\n '2xl': {\n container: 'p-8 gap-5',\n label: 'text-2xl',\n description: 'text-xl mt-2.5',\n errorMessage: 'text-base',\n },\n}\n\nconst LMRadio: React.FC<LMRadioProps> = ({\n label,\n description,\n error = false,\n errorMessage,\n size = 'md',\n className = '',\n id,\n ...props\n}) => {\n const autoId = useId()\n const controlId = id ?? `lm-radio-${autoId}`\n const errId = `lm-radio-err-${autoId}`\n\n const currentSize = sizeConfig[size]\n const radioSizeClass = SIZE_ICON_CONFIG[size]\n\n const getRadioStyles = () => {\n const baseStyles = {\n backgroundColor: 'var(--lm-bg-elevated)',\n borderColor: error\n ? 'var(--lm-error-300)'\n : 'var(--lm-border-default)',\n color: 'var(--lm-primary-500)',\n } as React.CSSProperties\n\n return {\n ...baseStyles,\n '--tw-ring-color': error\n ? 'var(--lm-error-400)'\n : 'var(--lm-primary-400)',\n '--tw-ring-opacity': '0.3',\n }\n }\n\n const getDisabledStyles = () => {\n if (props.disabled) {\n return {\n backgroundColor: 'var(--lm-bg-paper)',\n borderColor: 'var(--lm-border-light)',\n color: 'var(--lm-text-disabled)',\n cursor: 'not-allowed',\n opacity: 0.6,\n } as React.CSSProperties\n }\n return {}\n }\n\n const getContainerStyles = () => {\n const base = { backgroundColor: 'var(--lm-bg-paper)' }\n return error ? { ...base, backgroundColor: 'var(--lm-error-50)' } : base\n }\n\n const getHoverContainerStyles = () =>\n error\n ? { backgroundColor: 'var(--lm-error-100)' }\n : { backgroundColor: 'var(--lm-bg-elevated)' }\n\n const getLabelStyles = () => {\n if (error) return { color: 'var(--lm-error-700)' }\n if (props.disabled)\n return { color: 'var(--lm-text-disabled)', cursor: 'not-allowed' }\n return { color: 'var(--lm-text-primary)', cursor: 'pointer' }\n }\n\n const getDescriptionStyles = () =>\n error\n ? { color: 'var(--lm-error-600)' }\n : { color: 'var(--lm-text-secondary)' }\n\n const radioClassName = cn(\n radioSizeClass,\n 'border-2 rounded-full',\n 'focus:ring-2 focus:ring-offset-0',\n 'transition-all duration-200',\n className\n )\n\n return (\n <div>\n <div\n className={`flex items-start ${currentSize.container} rounded-2xl transition-colors duration-200`}\n style={getContainerStyles()}\n onMouseEnter={(e) => {\n if (!props.disabled)\n Object.assign(e.currentTarget.style, getHoverContainerStyles())\n }}\n onMouseLeave={(e) => {\n if (!props.disabled)\n Object.assign(e.currentTarget.style, getContainerStyles())\n }}\n >\n <input\n type=\"radio\"\n id={controlId}\n {...props}\n className={radioClassName}\n aria-invalid={error || undefined}\n aria-describedby={errorMessage ? errId : undefined}\n style={{ ...getRadioStyles(), ...getDisabledStyles() } as React.CSSProperties}\n onFocus={(e) => {\n if (!props.disabled) {\n e.currentTarget.style.borderColor = error\n ? 'var(--lm-error-400)'\n : 'var(--lm-primary-400)'\n }\n props.onFocus?.(e)\n }}\n onBlur={(e) => {\n if (!props.disabled) {\n e.currentTarget.style.borderColor = error\n ? 'var(--lm-error-300)'\n : 'var(--lm-border-default)'\n }\n props.onBlur?.(e)\n }}\n />\n\n <div className=\"flex-1\">\n <label\n htmlFor={controlId}\n className={`${currentSize.label} font-medium transition-colors duration-200`}\n style={getLabelStyles()}\n >\n {label}\n </label>\n {description && (\n <p className={currentSize.description} style={getDescriptionStyles()}>\n {description}\n </p>\n )}\n </div>\n </div>\n\n {errorMessage && <ErrorMessage message={errorMessage} />}\n </div>\n )\n}\n\nexport default LMRadio\n"],"names":[],"mappings":"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"}