@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
@@ -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 LMSearchInput = ({
6
+ const ErrorMessage = require("./ErrorMessage-CbE7emgD.cjs");
7
+ const LMSearchInput = React.forwardRef(({
6
8
  value,
7
9
  onChange,
8
10
  onSearch,
@@ -17,11 +19,16 @@ const LMSearchInput = ({
17
19
  showSearchButton = true,
18
20
  searchButtonText = "Search",
19
21
  debounceDelay = 300
20
- }) => {
22
+ }, ref) => {
21
23
  const [inputValue, setInputValue] = React.useState(value || "");
22
24
  const [isFocused, setIsFocused] = React.useState(false);
23
25
  const debounceRef = React.useRef(null);
24
26
  const inputRef = React.useRef(null);
27
+ const setRefs = React.useCallback((node) => {
28
+ inputRef.current = node;
29
+ if (typeof ref === "function") ref(node);
30
+ else if (ref) ref.current = node;
31
+ }, [ref]);
25
32
  const searchBtnRef = React.useRef(null);
26
33
  const [searchBtnWidth, setSearchBtnWidth] = React.useState(0);
27
34
  React.useEffect(() => {
@@ -34,14 +41,17 @@ const LMSearchInput = ({
34
41
  setSearchBtnWidth(0);
35
42
  }
36
43
  }, [showSearchButton, searchButtonText]);
37
- const baseClassName = `
38
- w-full ${componentSizes.SIZE_INPUT_CONFIG[size].padding} ${componentSizes.SIZE_INPUT_CONFIG[size].height} backdrop-blur-md border rounded-2xl
39
- focus:ring-2 focus:outline-none transition-all duration-300
40
- shadow-sm
41
- ${showSearchButton ? "pr-20" : showClear ? "pr-10" : "pr-4"}
42
- pl-12
43
- ${className}
44
- `.trim().replace(/\s+/g, " ");
44
+ const baseClassName = cn.cn(
45
+ "w-full",
46
+ componentSizes.SIZE_INPUT_CONFIG[size].padding,
47
+ componentSizes.SIZE_INPUT_CONFIG[size].height,
48
+ "backdrop-blur-md border rounded-2xl",
49
+ "focus:ring-2 focus:outline-none transition-all duration-300",
50
+ "shadow-sm",
51
+ showSearchButton ? "pr-20" : showClear ? "pr-10" : "pr-4",
52
+ "pl-12",
53
+ className
54
+ );
45
55
  const getSearchInputStyles = () => {
46
56
  const baseStyles = {
47
57
  backgroundColor: "var(--lm-bg-elevated)",
@@ -107,7 +117,7 @@ const LMSearchInput = ({
107
117
  /* @__PURE__ */ jsxRuntime.jsx(
108
118
  "input",
109
119
  {
110
- ref: inputRef,
120
+ ref: setRefs,
111
121
  type: "search",
112
122
  name,
113
123
  value: inputValue,
@@ -180,25 +190,9 @@ const LMSearchInput = ({
180
190
  }
181
191
  )
182
192
  ] }),
183
- errorMessage && /* @__PURE__ */ jsxRuntime.jsxs(
184
- "p",
185
- {
186
- className: "text-xs flex items-center gap-1",
187
- style: { color: "var(--lm-error-500)" },
188
- children: [
189
- /* @__PURE__ */ jsxRuntime.jsx("svg", { className: "w-3 h-3", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ jsxRuntime.jsx(
190
- "path",
191
- {
192
- fillRule: "evenodd",
193
- 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",
194
- clipRule: "evenodd"
195
- }
196
- ) }),
197
- errorMessage
198
- ]
199
- }
200
- )
193
+ errorMessage && /* @__PURE__ */ jsxRuntime.jsx(ErrorMessage.ErrorMessage, { message: errorMessage })
201
194
  ] });
202
- };
195
+ });
196
+ LMSearchInput.displayName = "LMSearchInput";
203
197
  exports.LMSearchInput = LMSearchInput;
204
- //# sourceMappingURL=LMSearchInput-nBlAX734.cjs.map
198
+ //# sourceMappingURL=LMSearchInput-BDJVh4Vs.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LMSearchInput-BDJVh4Vs.cjs","sources":["../src/components/Form/LMSearchInput/LMSearchInput.tsx"],"sourcesContent":["import React, { useState, useRef, useEffect, useCallback } 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 LMSearchInputProps {\n /** Current search value */\n value?: string\n /** Change callback */\n onChange?: (value: string) => void\n /** Search submit callback */\n onSearch?: (value: string) => 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 /** Show clear button */\n showClear?: boolean\n /** Show search button */\n showSearchButton?: boolean\n /** Search button text */\n searchButtonText?: string\n /** Debounce delay (ms) */\n debounceDelay?: number\n}\n\nconst LMSearchInput = React.forwardRef<HTMLInputElement, LMSearchInputProps>(({\n value,\n onChange,\n onSearch,\n error = false,\n errorMessage,\n placeholder = 'Search...',\n disabled = false,\n className = '',\n name,\n size = 'md',\n showClear = true,\n showSearchButton = true,\n searchButtonText = 'Search',\n debounceDelay = 300,\n}, ref) => {\n const [inputValue, setInputValue] = useState(value || '')\n const [isFocused, setIsFocused] = useState(false)\n const debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null)\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 searchBtnRef = useRef<HTMLButtonElement>(null)\n const [searchBtnWidth, setSearchBtnWidth] = useState(0)\n\n useEffect(() => {\n if (value !== undefined && value !== null) setInputValue(value)\n }, [value])\n\n useEffect(() => {\n if (showSearchButton && searchBtnRef.current) {\n setSearchBtnWidth(searchBtnRef.current.offsetWidth || 0)\n } else {\n setSearchBtnWidth(0)\n }\n }, [showSearchButton, searchButtonText])\n\n const baseClassName = cn(\n 'w-full',\n SIZE_INPUT_CONFIG[size].padding,\n SIZE_INPUT_CONFIG[size].height,\n 'backdrop-blur-md border rounded-2xl',\n 'focus:ring-2 focus:outline-none transition-all duration-300',\n 'shadow-sm',\n showSearchButton ? 'pr-20' : showClear ? 'pr-10' : 'pr-4',\n 'pl-12',\n className\n )\n\n const getSearchInputStyles = () => {\n const baseStyles = {\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 ...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 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 getButtonStyles = () => ({\n backgroundColor: 'var(--lm-primary-500)',\n color: 'white',\n })\n\n const getClearButtonStyles = () => ({\n backgroundColor: 'var(--lm-bg-paper)',\n color: 'var(--lm-text-secondary)',\n })\n\n const handleInputChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n const newValue = event.target.value\n setInputValue(newValue)\n onChange?.(newValue)\n\n if (debounceRef.current) clearTimeout(debounceRef.current)\n debounceRef.current = setTimeout(() => {\n onSearch?.(newValue)\n }, debounceDelay)\n }\n\n const handleSearch = () => onSearch?.(inputValue)\n\n const handleClear = () => {\n setInputValue('')\n onChange?.('')\n onSearch?.('')\n inputRef.current?.focus()\n }\n\n const handleKeyDown = (event: React.KeyboardEvent) => {\n if (event.key === 'Enter') {\n event.preventDefault()\n handleSearch()\n }\n }\n\n const clearBtnSizeClass =\n size === 'sm'\n ? 'w-7 h-7 text-xs'\n : size === 'lg'\n ? 'w-9 h-9 text-sm'\n : 'w-8 h-8 text-sm'\n\n const clearRightPx = showSearchButton ? searchBtnWidth + 8 : 8\n\n const SearchIcon = () => (\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=\"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z\" />\n </svg>\n )\n\n const ClearIcon = () => (\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=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n )\n\n return (\n <div className=\"space-y-2\">\n <div className=\"relative group\">\n <div className=\"absolute inset-y-0 left-0 pl-4 flex items-center pointer-events-none z-10\">\n <span style={getIconStyles()}>\n <SearchIcon />\n </span>\n </div>\n\n <input\n ref={setRefs}\n type=\"search\"\n name={name}\n value={inputValue}\n placeholder={placeholder}\n disabled={disabled}\n className={baseClassName}\n style={{\n ...getSearchInputStyles(),\n ...getDisabledStyles(),\n } as React.CSSProperties}\n onChange={handleInputChange}\n onKeyDown={handleKeyDown}\n onFocus={() => setIsFocused(true)}\n onBlur={() => setIsFocused(false)}\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 <style>{`\n input[type='search']::-webkit-search-cancel-button {\n -webkit-appearance: none;\n appearance: none;\n }\n `}</style>\n\n {showClear && inputValue && !disabled && (\n <button\n onClick={handleClear}\n className={`absolute top-1/2 -translate-y-1/2 z-10 rounded-full flex items-center justify-center ${clearBtnSizeClass}`}\n style={{\n ...getClearButtonStyles(),\n right: `${clearRightPx}px`,\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.backgroundColor = 'var(--lm-bg-elevated)'\n e.currentTarget.style.color = 'var(--lm-text-primary)'\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.backgroundColor = 'var(--lm-bg-paper)'\n e.currentTarget.style.color = 'var(--lm-text-secondary)'\n }}\n aria-label=\"Clear\"\n type=\"button\"\n >\n <ClearIcon />\n </button>\n )}\n\n {showSearchButton && !disabled && (\n <button\n ref={searchBtnRef}\n onClick={handleSearch}\n className=\"absolute inset-y-0 right-0 px-4 rounded-r-2xl transition-colors duration-200 z-20\"\n style={getButtonStyles()}\n onMouseEnter={(e) => {\n e.currentTarget.style.backgroundColor = 'var(--lm-primary-600)'\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.backgroundColor = 'var(--lm-primary-500)'\n }}\n type=\"button\"\n >\n <span className=\"text-sm font-medium\">{searchButtonText}</span>\n </button>\n )}\n </div>\n\n {errorMessage && <ErrorMessage message={errorMessage} />}\n </div>\n )\n})\n\nLMSearchInput.displayName = 'LMSearchInput'\n\nexport default LMSearchInput\n"],"names":["useState","useRef","useCallback","useEffect","cn","SIZE_INPUT_CONFIG","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, useEffect } from "react";
2
+ import React, { useState, useRef, useCallback, useEffect } 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 LMSearchInput = ({
5
+ import { E as ErrorMessage } from "./ErrorMessage-Dt4cJ-sy.js";
6
+ const LMSearchInput = React.forwardRef(({
5
7
  value,
6
8
  onChange,
7
9
  onSearch,
@@ -16,11 +18,16 @@ const LMSearchInput = ({
16
18
  showSearchButton = true,
17
19
  searchButtonText = "Search",
18
20
  debounceDelay = 300
19
- }) => {
21
+ }, ref) => {
20
22
  const [inputValue, setInputValue] = useState(value || "");
21
23
  const [isFocused, setIsFocused] = useState(false);
22
24
  const debounceRef = useRef(null);
23
25
  const inputRef = useRef(null);
26
+ const setRefs = useCallback((node) => {
27
+ inputRef.current = node;
28
+ if (typeof ref === "function") ref(node);
29
+ else if (ref) ref.current = node;
30
+ }, [ref]);
24
31
  const searchBtnRef = useRef(null);
25
32
  const [searchBtnWidth, setSearchBtnWidth] = useState(0);
26
33
  useEffect(() => {
@@ -33,14 +40,17 @@ const LMSearchInput = ({
33
40
  setSearchBtnWidth(0);
34
41
  }
35
42
  }, [showSearchButton, searchButtonText]);
36
- const baseClassName = `
37
- w-full ${SIZE_INPUT_CONFIG[size].padding} ${SIZE_INPUT_CONFIG[size].height} backdrop-blur-md border rounded-2xl
38
- focus:ring-2 focus:outline-none transition-all duration-300
39
- shadow-sm
40
- ${showSearchButton ? "pr-20" : showClear ? "pr-10" : "pr-4"}
41
- pl-12
42
- ${className}
43
- `.trim().replace(/\s+/g, " ");
43
+ const baseClassName = cn(
44
+ "w-full",
45
+ SIZE_INPUT_CONFIG[size].padding,
46
+ SIZE_INPUT_CONFIG[size].height,
47
+ "backdrop-blur-md border rounded-2xl",
48
+ "focus:ring-2 focus:outline-none transition-all duration-300",
49
+ "shadow-sm",
50
+ showSearchButton ? "pr-20" : showClear ? "pr-10" : "pr-4",
51
+ "pl-12",
52
+ className
53
+ );
44
54
  const getSearchInputStyles = () => {
45
55
  const baseStyles = {
46
56
  backgroundColor: "var(--lm-bg-elevated)",
@@ -106,7 +116,7 @@ const LMSearchInput = ({
106
116
  /* @__PURE__ */ jsx(
107
117
  "input",
108
118
  {
109
- ref: inputRef,
119
+ ref: setRefs,
110
120
  type: "search",
111
121
  name,
112
122
  value: inputValue,
@@ -179,27 +189,11 @@ const LMSearchInput = ({
179
189
  }
180
190
  )
181
191
  ] }),
182
- errorMessage && /* @__PURE__ */ jsxs(
183
- "p",
184
- {
185
- className: "text-xs flex items-center gap-1",
186
- style: { color: "var(--lm-error-500)" },
187
- children: [
188
- /* @__PURE__ */ jsx("svg", { className: "w-3 h-3", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ jsx(
189
- "path",
190
- {
191
- fillRule: "evenodd",
192
- 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",
193
- clipRule: "evenodd"
194
- }
195
- ) }),
196
- errorMessage
197
- ]
198
- }
199
- )
192
+ errorMessage && /* @__PURE__ */ jsx(ErrorMessage, { message: errorMessage })
200
193
  ] });
201
- };
194
+ });
195
+ LMSearchInput.displayName = "LMSearchInput";
202
196
  export {
203
197
  LMSearchInput as L
204
198
  };
205
- //# sourceMappingURL=LMSearchInput-CIvVkEf2.js.map
199
+ //# sourceMappingURL=LMSearchInput-DQovqMTN.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LMSearchInput-DQovqMTN.js","sources":["../src/components/Form/LMSearchInput/LMSearchInput.tsx"],"sourcesContent":["import React, { useState, useRef, useEffect, useCallback } 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 LMSearchInputProps {\n /** Current search value */\n value?: string\n /** Change callback */\n onChange?: (value: string) => void\n /** Search submit callback */\n onSearch?: (value: string) => 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 /** Show clear button */\n showClear?: boolean\n /** Show search button */\n showSearchButton?: boolean\n /** Search button text */\n searchButtonText?: string\n /** Debounce delay (ms) */\n debounceDelay?: number\n}\n\nconst LMSearchInput = React.forwardRef<HTMLInputElement, LMSearchInputProps>(({\n value,\n onChange,\n onSearch,\n error = false,\n errorMessage,\n placeholder = 'Search...',\n disabled = false,\n className = '',\n name,\n size = 'md',\n showClear = true,\n showSearchButton = true,\n searchButtonText = 'Search',\n debounceDelay = 300,\n}, ref) => {\n const [inputValue, setInputValue] = useState(value || '')\n const [isFocused, setIsFocused] = useState(false)\n const debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null)\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 searchBtnRef = useRef<HTMLButtonElement>(null)\n const [searchBtnWidth, setSearchBtnWidth] = useState(0)\n\n useEffect(() => {\n if (value !== undefined && value !== null) setInputValue(value)\n }, [value])\n\n useEffect(() => {\n if (showSearchButton && searchBtnRef.current) {\n setSearchBtnWidth(searchBtnRef.current.offsetWidth || 0)\n } else {\n setSearchBtnWidth(0)\n }\n }, [showSearchButton, searchButtonText])\n\n const baseClassName = cn(\n 'w-full',\n SIZE_INPUT_CONFIG[size].padding,\n SIZE_INPUT_CONFIG[size].height,\n 'backdrop-blur-md border rounded-2xl',\n 'focus:ring-2 focus:outline-none transition-all duration-300',\n 'shadow-sm',\n showSearchButton ? 'pr-20' : showClear ? 'pr-10' : 'pr-4',\n 'pl-12',\n className\n )\n\n const getSearchInputStyles = () => {\n const baseStyles = {\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 ...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 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 getButtonStyles = () => ({\n backgroundColor: 'var(--lm-primary-500)',\n color: 'white',\n })\n\n const getClearButtonStyles = () => ({\n backgroundColor: 'var(--lm-bg-paper)',\n color: 'var(--lm-text-secondary)',\n })\n\n const handleInputChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n const newValue = event.target.value\n setInputValue(newValue)\n onChange?.(newValue)\n\n if (debounceRef.current) clearTimeout(debounceRef.current)\n debounceRef.current = setTimeout(() => {\n onSearch?.(newValue)\n }, debounceDelay)\n }\n\n const handleSearch = () => onSearch?.(inputValue)\n\n const handleClear = () => {\n setInputValue('')\n onChange?.('')\n onSearch?.('')\n inputRef.current?.focus()\n }\n\n const handleKeyDown = (event: React.KeyboardEvent) => {\n if (event.key === 'Enter') {\n event.preventDefault()\n handleSearch()\n }\n }\n\n const clearBtnSizeClass =\n size === 'sm'\n ? 'w-7 h-7 text-xs'\n : size === 'lg'\n ? 'w-9 h-9 text-sm'\n : 'w-8 h-8 text-sm'\n\n const clearRightPx = showSearchButton ? searchBtnWidth + 8 : 8\n\n const SearchIcon = () => (\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=\"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z\" />\n </svg>\n )\n\n const ClearIcon = () => (\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=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n )\n\n return (\n <div className=\"space-y-2\">\n <div className=\"relative group\">\n <div className=\"absolute inset-y-0 left-0 pl-4 flex items-center pointer-events-none z-10\">\n <span style={getIconStyles()}>\n <SearchIcon />\n </span>\n </div>\n\n <input\n ref={setRefs}\n type=\"search\"\n name={name}\n value={inputValue}\n placeholder={placeholder}\n disabled={disabled}\n className={baseClassName}\n style={{\n ...getSearchInputStyles(),\n ...getDisabledStyles(),\n } as React.CSSProperties}\n onChange={handleInputChange}\n onKeyDown={handleKeyDown}\n onFocus={() => setIsFocused(true)}\n onBlur={() => setIsFocused(false)}\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 <style>{`\n input[type='search']::-webkit-search-cancel-button {\n -webkit-appearance: none;\n appearance: none;\n }\n `}</style>\n\n {showClear && inputValue && !disabled && (\n <button\n onClick={handleClear}\n className={`absolute top-1/2 -translate-y-1/2 z-10 rounded-full flex items-center justify-center ${clearBtnSizeClass}`}\n style={{\n ...getClearButtonStyles(),\n right: `${clearRightPx}px`,\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.backgroundColor = 'var(--lm-bg-elevated)'\n e.currentTarget.style.color = 'var(--lm-text-primary)'\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.backgroundColor = 'var(--lm-bg-paper)'\n e.currentTarget.style.color = 'var(--lm-text-secondary)'\n }}\n aria-label=\"Clear\"\n type=\"button\"\n >\n <ClearIcon />\n </button>\n )}\n\n {showSearchButton && !disabled && (\n <button\n ref={searchBtnRef}\n onClick={handleSearch}\n className=\"absolute inset-y-0 right-0 px-4 rounded-r-2xl transition-colors duration-200 z-20\"\n style={getButtonStyles()}\n onMouseEnter={(e) => {\n e.currentTarget.style.backgroundColor = 'var(--lm-primary-600)'\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.backgroundColor = 'var(--lm-primary-500)'\n }}\n type=\"button\"\n >\n <span className=\"text-sm font-medium\">{searchButtonText}</span>\n </button>\n )}\n </div>\n\n {errorMessage && <ErrorMessage message={errorMessage} />}\n </div>\n )\n})\n\nLMSearchInput.displayName = 'LMSearchInput'\n\nexport default LMSearchInput\n"],"names":[],"mappings":"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"}
@@ -1,6 +1,8 @@
1
1
  import { jsxs, jsx } from "react/jsx-runtime";
2
2
  import { useState, useRef, useEffect } from "react";
3
+ import { c as cn } from "./cn-wDEkOmcn.js";
3
4
  import { d as SIZE_SELECTOR_CONFIG } from "./componentSizes-CdWNL526.js";
5
+ import { E as ErrorMessage } from "./ErrorMessage-Dt4cJ-sy.js";
4
6
  const SIZE_DROPDOWN_CONFIG = {
5
7
  xs: { maxHeight: "max-h-32", optionPadding: "px-3 py-1.5", optionTextSize: "text-xs" },
6
8
  sm: { maxHeight: "max-h-40", optionPadding: "px-3 py-2", optionTextSize: "text-xs" },
@@ -9,6 +11,8 @@ const SIZE_DROPDOWN_CONFIG = {
9
11
  xl: { maxHeight: "max-h-64", optionPadding: "px-5 py-3", optionTextSize: "text-base" },
10
12
  "2xl": { maxHeight: "max-h-72", optionPadding: "px-6 py-4", optionTextSize: "text-lg" }
11
13
  };
14
+ const ChevronDownIcon = () => /* @__PURE__ */ jsx("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 9l-7 7-7-7" }) });
15
+ const CheckIcon = () => /* @__PURE__ */ jsx("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 13l4 4L19 7" }) });
12
16
  const LMSelect = ({
13
17
  options,
14
18
  value,
@@ -78,13 +82,16 @@ const LMSelect = ({
78
82
  onDropdownVisibleChange == null ? void 0 : onDropdownVisibleChange(newIsOpen);
79
83
  }
80
84
  };
81
- const baseClassName = `
82
- w-full ${SIZE_SELECTOR_CONFIG[size].padding} ${SIZE_SELECTOR_CONFIG[size].height} ${SIZE_SELECTOR_CONFIG[size].fontSize}
83
- border rounded-xl
84
- cursor-pointer select-none
85
- flex items-center justify-between
86
- ${className}
87
- `.trim().replace(/\s+/g, " ");
85
+ const baseClassName = cn(
86
+ "w-full",
87
+ SIZE_SELECTOR_CONFIG[size].padding,
88
+ SIZE_SELECTOR_CONFIG[size].height,
89
+ SIZE_SELECTOR_CONFIG[size].fontSize,
90
+ "border rounded-xl",
91
+ "cursor-pointer select-none",
92
+ "flex items-center justify-between",
93
+ className
94
+ );
88
95
  const getSelectorStyles = () => {
89
96
  const baseStyles = {
90
97
  backgroundColor: "var(--lm-bg-elevated)",
@@ -148,18 +155,6 @@ const LMSelect = ({
148
155
  }
149
156
  return selectedOption ? selectedOption.label : placeholder;
150
157
  };
151
- const ChevronDown = () => /* @__PURE__ */ jsx(
152
- "svg",
153
- {
154
- className: `w-4 h-4 transition-transform duration-200 ${isOpen ? "rotate-180" : ""}`,
155
- fill: "none",
156
- stroke: "currentColor",
157
- viewBox: "0 0 24 24",
158
- style: getIconStyles(),
159
- children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 9l-7 7-7-7" })
160
- }
161
- );
162
- const CheckIcon = () => /* @__PURE__ */ jsx("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 13l4 4L19 7" }) });
163
158
  return /* @__PURE__ */ jsxs("div", { className: "relative", ref: dropdownRef, children: [
164
159
  /* @__PURE__ */ jsx(
165
160
  "select",
@@ -180,7 +175,9 @@ const LMSelect = ({
180
175
  {
181
176
  className: baseClassName,
182
177
  onClick: toggleDropdown,
183
- role: "button",
178
+ role: "combobox",
179
+ "aria-expanded": isOpen,
180
+ "aria-haspopup": "listbox",
184
181
  tabIndex: disabled ? -1 : 0,
185
182
  style: {
186
183
  ...getSelectorStyles(),
@@ -222,13 +219,21 @@ const LMSelect = ({
222
219
  children: getDisplayText()
223
220
  }
224
221
  ),
225
- /* @__PURE__ */ jsx(ChevronDown, {})
222
+ /* @__PURE__ */ jsx(
223
+ "span",
224
+ {
225
+ className: `transition-transform duration-200 ${isOpen ? "rotate-180" : ""}`,
226
+ style: getIconStyles(),
227
+ children: /* @__PURE__ */ jsx(ChevronDownIcon, {})
228
+ }
229
+ )
226
230
  ]
227
231
  }
228
232
  ),
229
233
  isOpen && /* @__PURE__ */ jsx(
230
234
  "div",
231
235
  {
236
+ role: "listbox",
232
237
  className: `absolute left-0 right-0 z-50 border rounded-xl overflow-y-auto ${SIZE_DROPDOWN_CONFIG[size].maxHeight}`,
233
238
  style: {
234
239
  ...getDropdownStyles(),
@@ -237,14 +242,15 @@ const LMSelect = ({
237
242
  children: options.map((option, index) => /* @__PURE__ */ jsx(
238
243
  "div",
239
244
  {
240
- className: `
241
- ${SIZE_DROPDOWN_CONFIG[size].optionPadding} ${SIZE_DROPDOWN_CONFIG[size].optionTextSize} font-medium
242
- cursor-pointer transition-all duration-150
243
- ${option.disabled ? "cursor-not-allowed" : ""}
244
- ${index === 0 ? "rounded-t-xl" : ""}
245
- ${index === options.length - 1 ? "rounded-b-xl" : ""}
246
- ${index > 0 ? "border-t" : ""}
247
- `,
245
+ className: cn(
246
+ SIZE_DROPDOWN_CONFIG[size].optionPadding,
247
+ SIZE_DROPDOWN_CONFIG[size].optionTextSize,
248
+ "font-medium cursor-pointer transition-all duration-150",
249
+ option.disabled && "cursor-not-allowed",
250
+ index === 0 && "rounded-t-xl",
251
+ index === options.length - 1 && "rounded-b-xl",
252
+ index > 0 && "border-t"
253
+ ),
248
254
  style: {
249
255
  ...getOptionStyles(option),
250
256
  borderTopColor: index > 0 ? "var(--lm-border-light)" : "transparent"
@@ -283,27 +289,10 @@ const LMSelect = ({
283
289
  ))
284
290
  }
285
291
  ),
286
- errorMessage && /* @__PURE__ */ jsxs(
287
- "p",
288
- {
289
- className: "text-xs flex items-center gap-1 mt-2",
290
- style: { color: "var(--lm-error-500)" },
291
- children: [
292
- /* @__PURE__ */ jsx("svg", { className: "w-3 h-3", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ jsx(
293
- "path",
294
- {
295
- fillRule: "evenodd",
296
- 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",
297
- clipRule: "evenodd"
298
- }
299
- ) }),
300
- errorMessage
301
- ]
302
- }
303
- )
292
+ errorMessage && /* @__PURE__ */ jsx(ErrorMessage, { message: errorMessage, className: "mt-2" })
304
293
  ] });
305
294
  };
306
295
  export {
307
296
  LMSelect as L
308
297
  };
309
- //# sourceMappingURL=LMSelect-B-MWX2JI.js.map
298
+ //# sourceMappingURL=LMSelect-BPfW-AHI.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LMSelect-BPfW-AHI.js","sources":["../src/components/Form/LMSelect/LMSelect.tsx"],"sourcesContent":["import React, { useState, useRef, useEffect } from 'react'\nimport { cn } from '../../../utils/cn'\nimport { SIZE_SELECTOR_CONFIG } from '../../../utils/componentSizes'\nimport type { ComponentSize } from '../../../utils/componentSizes'\nimport { ErrorMessage } from '../../_internal/ErrorMessage'\n\nexport interface LMSelectOption {\n value: string | number\n label: string\n disabled?: boolean\n}\n\nexport interface LMSelectProps {\n /** Options */\n options: LMSelectOption[]\n /** Current value */\n value?: string | number | (string | number)[]\n /** Change callback */\n onChange?: (value: string | number | (string | number)[]) => void\n /** Dropdown visibility change callback */\n onDropdownVisibleChange?: (visible: boolean) => 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 /** Multiple selection */\n multiple?: boolean\n}\n\nconst SIZE_DROPDOWN_CONFIG: Record<\n ComponentSize,\n {\n maxHeight: string\n optionPadding: string\n optionTextSize: string\n }\n> = {\n xs: { maxHeight: 'max-h-32', optionPadding: 'px-3 py-1.5', optionTextSize: 'text-xs' },\n sm: { maxHeight: 'max-h-40', optionPadding: 'px-3 py-2', optionTextSize: 'text-xs' },\n md: { maxHeight: 'max-h-48', optionPadding: 'px-4 py-2.5', optionTextSize: 'text-sm' },\n lg: { maxHeight: 'max-h-56', optionPadding: 'px-4 py-3', optionTextSize: 'text-sm' },\n xl: { maxHeight: 'max-h-64', optionPadding: 'px-5 py-3', optionTextSize: 'text-base' },\n '2xl': { maxHeight: 'max-h-72', optionPadding: 'px-6 py-4', optionTextSize: 'text-lg' },\n}\n\nconst ChevronDownIcon: 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=\"M19 9l-7 7-7-7\" />\n </svg>\n)\n\nconst CheckIcon: 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=\"M5 13l4 4L19 7\" />\n </svg>\n)\n\nconst LMSelect: React.FC<LMSelectProps> = ({\n options,\n value,\n onChange,\n onDropdownVisibleChange,\n error = false,\n errorMessage,\n placeholder = 'Select...',\n disabled = false,\n className = '',\n name,\n size = 'md',\n multiple = false,\n}) => {\n const [isOpen, setIsOpen] = useState(false)\n const [selectedOption, setSelectedOption] = useState<LMSelectOption | null>(null)\n const [selectedOptions, setSelectedOptions] = useState<LMSelectOption[]>([])\n const dropdownRef = useRef<HTMLDivElement>(null)\n\n useEffect(() => {\n if (!multiple) {\n if (value !== undefined && value !== null && !Array.isArray(value)) {\n const option = options.find((opt) => opt.value === value)\n setSelectedOption(option || null)\n } else {\n setSelectedOption(null)\n }\n }\n }, [value, options, multiple])\n\n useEffect(() => {\n if (multiple && Array.isArray(value)) {\n const selectedOpts = options.filter((opt) => value.includes(opt.value))\n setSelectedOptions(selectedOpts)\n } else if (multiple) {\n setSelectedOptions([])\n }\n }, [value, options, multiple])\n\n useEffect(() => {\n const handleClickOutside = (event: MouseEvent) => {\n if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) {\n setIsOpen(false)\n onDropdownVisibleChange?.(false)\n }\n }\n\n if (isOpen) {\n document.addEventListener('mousedown', handleClickOutside)\n return () => document.removeEventListener('mousedown', handleClickOutside)\n }\n }, [isOpen, onDropdownVisibleChange])\n\n const handleSelect = (option: LMSelectOption) => {\n if (option.disabled) return\n\n if (multiple) {\n const currentValues = Array.isArray(value) ? value : []\n const isSelected = currentValues.includes(option.value)\n const newValues = isSelected\n ? currentValues.filter((v) => v !== option.value)\n : [...currentValues, option.value]\n onChange?.(newValues)\n } else {\n setSelectedOption(option)\n onChange?.(option.value)\n setIsOpen(false)\n onDropdownVisibleChange?.(false)\n }\n }\n\n const toggleDropdown = () => {\n if (!disabled) {\n const newIsOpen = !isOpen\n setIsOpen(newIsOpen)\n onDropdownVisibleChange?.(newIsOpen)\n }\n }\n\n // Apple-like refined select styling\n const baseClassName = cn(\n 'w-full',\n SIZE_SELECTOR_CONFIG[size].padding,\n SIZE_SELECTOR_CONFIG[size].height,\n SIZE_SELECTOR_CONFIG[size].fontSize,\n 'border rounded-xl',\n 'cursor-pointer select-none',\n 'flex items-center justify-between',\n className\n )\n\n const getSelectorStyles = () => {\n // Apple-like refined select styles\n const baseStyles = {\n backgroundColor: 'var(--lm-bg-elevated)',\n color: 'var(--lm-text-primary)',\n borderColor: error ? 'var(--lm-error-300)' : 'var(--lm-border-default)',\n boxShadow: 'var(--lm-shadow-sm)',\n transition: 'all var(--lm-transition-fast) var(--lm-ease-out)',\n }\n\n return {\n ...baseStyles,\n '--tw-ring-color': error ? 'var(--lm-error-400)' : 'var(--lm-primary-400)',\n '--tw-ring-opacity': '0.4',\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 error ? { color: 'var(--lm-error-400)' } : { color: 'var(--lm-text-secondary)' }\n\n // Apple-like refined dropdown styles\n const getDropdownStyles = () => ({\n backgroundColor: 'var(--lm-bg-elevated)',\n borderColor: 'var(--lm-border-default)',\n boxShadow: 'var(--lm-shadow-lg)',\n backdropFilter: 'blur(20px) saturate(180%)',\n WebkitBackdropFilter: 'blur(20px) saturate(180%)',\n })\n\n const isOptionSelected = (optionValue: string | number): boolean => {\n if (multiple) {\n return Array.isArray(value) && value.includes(optionValue)\n }\n return selectedOption?.value === optionValue\n }\n\n const getOptionStyles = (option: LMSelectOption) => {\n const baseStyles = {\n color: option.disabled ? 'var(--lm-text-disabled)' : 'var(--lm-text-primary)',\n backgroundColor: option.disabled ? 'var(--lm-bg-paper)' : 'transparent',\n }\n\n if (isOptionSelected(option.value)) {\n return {\n ...baseStyles,\n backgroundColor: 'var(--lm-primary-50)',\n color: 'var(--lm-primary-700)',\n }\n }\n\n return baseStyles\n }\n\n const getHoverOptionStyles = (option: LMSelectOption) => {\n if (option.disabled) return {}\n\n if (isOptionSelected(option.value)) {\n return { backgroundColor: 'var(--lm-primary-100)' }\n }\n\n return { backgroundColor: 'var(--lm-bg-paper)' }\n }\n\n const getDisplayText = (): string => {\n if (multiple) {\n if (selectedOptions.length === 0) return placeholder\n if (selectedOptions.length === 1) return selectedOptions[0].label\n return `${selectedOptions.length} selected`\n }\n return selectedOption ? selectedOption.label : placeholder\n }\n\n return (\n <div className=\"relative\" ref={dropdownRef}>\n <select\n name={name}\n value={\n multiple\n ? Array.isArray(value)\n ? value.map(String)\n : []\n : value !== undefined && value !== null && !Array.isArray(value)\n ? String(value)\n : ''\n }\n // Empty handler to suppress React controlled component warning for hidden native select\n onChange={() => {}}\n className=\"sr-only\"\n disabled={disabled}\n tabIndex={-1}\n multiple={multiple}\n >\n {options.map((option) => (\n <option key={option.value} value={option.value} disabled={option.disabled}>\n {option.label}\n </option>\n ))}\n </select>\n\n <div\n className={baseClassName}\n onClick={toggleDropdown}\n role=\"combobox\"\n aria-expanded={isOpen}\n aria-haspopup=\"listbox\"\n tabIndex={disabled ? -1 : 0}\n style={{\n ...getSelectorStyles(),\n ...getDisabledStyles(),\n } as React.CSSProperties}\n onMouseEnter={(e) => {\n if (!disabled && !error) {\n e.currentTarget.style.borderColor = 'var(--lm-border-strong)'\n }\n }}\n onMouseLeave={(e) => {\n if (!disabled && !error) {\n e.currentTarget.style.borderColor = 'var(--lm-border-default)'\n }\n }}\n onFocus={(e) => {\n if (!disabled) {\n e.currentTarget.style.borderColor = error\n ? 'var(--lm-error-400)'\n : 'var(--lm-primary-400)'\n }\n }}\n onBlur={(e) => {\n if (!disabled) {\n e.currentTarget.style.borderColor = error\n ? 'var(--lm-error-300)'\n : 'var(--lm-border-default)'\n }\n }}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n toggleDropdown()\n }\n }}\n >\n <span\n style={{\n color:\n (multiple && selectedOptions.length > 0) || selectedOption\n ? 'var(--lm-text-primary)'\n : 'var(--lm-text-secondary)',\n }}\n >\n {getDisplayText()}\n </span>\n <span\n className={`transition-transform duration-200 ${isOpen ? 'rotate-180' : ''}`}\n style={getIconStyles()}\n >\n <ChevronDownIcon />\n </span>\n </div>\n\n {isOpen && (\n <div\n role=\"listbox\"\n className={`absolute left-0 right-0 z-50 border rounded-xl overflow-y-auto ${SIZE_DROPDOWN_CONFIG[size].maxHeight}`}\n style={{\n ...getDropdownStyles(),\n top: 'calc(100% + 4px)',\n }}\n >\n {options.map((option, index) => (\n <div\n key={option.value}\n className={cn(\n SIZE_DROPDOWN_CONFIG[size].optionPadding,\n SIZE_DROPDOWN_CONFIG[size].optionTextSize,\n 'font-medium cursor-pointer transition-all duration-150',\n option.disabled && 'cursor-not-allowed',\n index === 0 && 'rounded-t-xl',\n index === options.length - 1 && 'rounded-b-xl',\n index > 0 && 'border-t'\n )}\n style={{\n ...getOptionStyles(option),\n borderTopColor: index > 0 ? 'var(--lm-border-light)' : 'transparent',\n }}\n onMouseEnter={(e) => {\n if (!option.disabled) {\n Object.assign(e.currentTarget.style, getHoverOptionStyles(option))\n }\n }}\n onMouseLeave={(e) => {\n if (!option.disabled) {\n Object.assign(e.currentTarget.style, getOptionStyles(option))\n }\n }}\n onClick={() => handleSelect(option)}\n role=\"option\"\n aria-selected={isOptionSelected(option.value)}\n >\n <div className=\"flex items-center justify-between\">\n {multiple && (\n <input\n type=\"checkbox\"\n checked={isOptionSelected(option.value)}\n // Empty handler: selection is handled by parent div onClick\n onChange={() => {}}\n className=\"mr-2 cursor-pointer\"\n style={{ accentColor: 'var(--lm-primary-500)' }}\n onClick={(e) => e.stopPropagation()}\n />\n )}\n <span className=\"truncate flex-1\">{option.label}</span>\n {!multiple && isOptionSelected(option.value) && (\n <span className=\"ml-2 shrink-0\" style={{ color: 'var(--lm-primary-600)' }}>\n <CheckIcon />\n </span>\n )}\n </div>\n </div>\n ))}\n </div>\n )}\n\n {errorMessage && <ErrorMessage message={errorMessage} className=\"mt-2\" />}\n </div>\n )\n}\n\nexport default LMSelect\n"],"names":[],"mappings":";;;;;AAuCA,MAAM,uBAOF;AAAA,EACF,IAAI,EAAE,WAAW,YAAY,eAAe,eAAe,gBAAgB,UAAA;AAAA,EAC3E,IAAI,EAAE,WAAW,YAAY,eAAe,aAAa,gBAAgB,UAAA;AAAA,EACzE,IAAI,EAAE,WAAW,YAAY,eAAe,eAAe,gBAAgB,UAAA;AAAA,EAC3E,IAAI,EAAE,WAAW,YAAY,eAAe,aAAa,gBAAgB,UAAA;AAAA,EACzE,IAAI,EAAE,WAAW,YAAY,eAAe,aAAa,gBAAgB,YAAA;AAAA,EACzE,OAAO,EAAE,WAAW,YAAY,eAAe,aAAa,gBAAgB,UAAA;AAC9E;AAEA,MAAM,kBAA4B,MAChC,oBAAC,OAAA,EAAI,WAAU,WAAU,MAAK,QAAO,QAAO,gBAAe,SAAQ,aACjE,UAAA,oBAAC,QAAA,EAAK,eAAc,SAAQ,gBAAe,SAAQ,aAAa,GAAG,GAAE,iBAAA,CAAiB,EAAA,CACxF;AAGF,MAAM,YAAsB,MAC1B,oBAAC,OAAA,EAAI,WAAU,WAAU,MAAK,QAAO,QAAO,gBAAe,SAAQ,aACjE,UAAA,oBAAC,QAAA,EAAK,eAAc,SAAQ,gBAAe,SAAQ,aAAa,GAAG,GAAE,iBAAA,CAAiB,EAAA,CACxF;AAGF,MAAM,WAAoC,CAAC;AAAA,EACzC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,QAAQ;AAAA,EACR;AAAA,EACA,cAAc;AAAA,EACd,WAAW;AAAA,EACX,YAAY;AAAA,EACZ;AAAA,EACA,OAAO;AAAA,EACP,WAAW;AACb,MAAM;AACJ,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAS,KAAK;AAC1C,QAAM,CAAC,gBAAgB,iBAAiB,IAAI,SAAgC,IAAI;AAChF,QAAM,CAAC,iBAAiB,kBAAkB,IAAI,SAA2B,CAAA,CAAE;AAC3E,QAAM,cAAc,OAAuB,IAAI;AAE/C,YAAU,MAAM;AACd,QAAI,CAAC,UAAU;AACb,UAAI,UAAU,UAAa,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK,GAAG;AAClE,cAAM,SAAS,QAAQ,KAAK,CAAC,QAAQ,IAAI,UAAU,KAAK;AACxD,0BAAkB,UAAU,IAAI;AAAA,MAClC,OAAO;AACL,0BAAkB,IAAI;AAAA,MACxB;AAAA,IACF;AAAA,EACF,GAAG,CAAC,OAAO,SAAS,QAAQ,CAAC;AAE7B,YAAU,MAAM;AACd,QAAI,YAAY,MAAM,QAAQ,KAAK,GAAG;AACpC,YAAM,eAAe,QAAQ,OAAO,CAAC,QAAQ,MAAM,SAAS,IAAI,KAAK,CAAC;AACtE,yBAAmB,YAAY;AAAA,IACjC,WAAW,UAAU;AACnB,yBAAmB,CAAA,CAAE;AAAA,IACvB;AAAA,EACF,GAAG,CAAC,OAAO,SAAS,QAAQ,CAAC;AAE7B,YAAU,MAAM;AACd,UAAM,qBAAqB,CAAC,UAAsB;AAChD,UAAI,YAAY,WAAW,CAAC,YAAY,QAAQ,SAAS,MAAM,MAAc,GAAG;AAC9E,kBAAU,KAAK;AACf,2EAA0B;AAAA,MAC5B;AAAA,IACF;AAEA,QAAI,QAAQ;AACV,eAAS,iBAAiB,aAAa,kBAAkB;AACzD,aAAO,MAAM,SAAS,oBAAoB,aAAa,kBAAkB;AAAA,IAC3E;AAAA,EACF,GAAG,CAAC,QAAQ,uBAAuB,CAAC;AAEpC,QAAM,eAAe,CAAC,WAA2B;AAC/C,QAAI,OAAO,SAAU;AAErB,QAAI,UAAU;AACZ,YAAM,gBAAgB,MAAM,QAAQ,KAAK,IAAI,QAAQ,CAAA;AACrD,YAAM,aAAa,cAAc,SAAS,OAAO,KAAK;AACtD,YAAM,YAAY,aACd,cAAc,OAAO,CAAC,MAAM,MAAM,OAAO,KAAK,IAC9C,CAAC,GAAG,eAAe,OAAO,KAAK;AACnC,2CAAW;AAAA,IACb,OAAO;AACL,wBAAkB,MAAM;AACxB,2CAAW,OAAO;AAClB,gBAAU,KAAK;AACf,yEAA0B;AAAA,IAC5B;AAAA,EACF;AAEA,QAAM,iBAAiB,MAAM;AAC3B,QAAI,CAAC,UAAU;AACb,YAAM,YAAY,CAAC;AACnB,gBAAU,SAAS;AACnB,yEAA0B;AAAA,IAC5B;AAAA,EACF;AAGA,QAAM,gBAAgB;AAAA,IACpB;AAAA,IACA,qBAAqB,IAAI,EAAE;AAAA,IAC3B,qBAAqB,IAAI,EAAE;AAAA,IAC3B,qBAAqB,IAAI,EAAE;AAAA,IAC3B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA;AAGF,QAAM,oBAAoB,MAAM;AAE9B,UAAM,aAAa;AAAA,MACjB,iBAAiB;AAAA,MACjB,OAAO;AAAA,MACP,aAAa,QAAQ,wBAAwB;AAAA,MAC7C,WAAW;AAAA,MACX,YAAY;AAAA,IAAA;AAGd,WAAO;AAAA,MACL,GAAG;AAAA,MACH,mBAAmB,QAAQ,wBAAwB;AAAA,MACnD,qBAAqB;AAAA,IAAA;AAAA,EAEzB;AAEA,QAAM,oBAAoB,MACxB,WACI;AAAA,IACE,iBAAiB;AAAA,IACjB,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,SAAS;AAAA,EAAA,IAEX,CAAA;AAEN,QAAM,gBAAgB,MACpB,QAAQ,EAAE,OAAO,0BAA0B,EAAE,OAAO,2BAAA;AAGtD,QAAM,oBAAoB,OAAO;AAAA,IAC/B,iBAAiB;AAAA,IACjB,aAAa;AAAA,IACb,WAAW;AAAA,IACX,gBAAgB;AAAA,IAChB,sBAAsB;AAAA,EAAA;AAGxB,QAAM,mBAAmB,CAAC,gBAA0C;AAClE,QAAI,UAAU;AACZ,aAAO,MAAM,QAAQ,KAAK,KAAK,MAAM,SAAS,WAAW;AAAA,IAC3D;AACA,YAAO,iDAAgB,WAAU;AAAA,EACnC;AAEA,QAAM,kBAAkB,CAAC,WAA2B;AAClD,UAAM,aAAa;AAAA,MACjB,OAAO,OAAO,WAAW,4BAA4B;AAAA,MACrD,iBAAiB,OAAO,WAAW,uBAAuB;AAAA,IAAA;AAG5D,QAAI,iBAAiB,OAAO,KAAK,GAAG;AAClC,aAAO;AAAA,QACL,GAAG;AAAA,QACH,iBAAiB;AAAA,QACjB,OAAO;AAAA,MAAA;AAAA,IAEX;AAEA,WAAO;AAAA,EACT;AAEA,QAAM,uBAAuB,CAAC,WAA2B;AACvD,QAAI,OAAO,SAAU,QAAO,CAAA;AAE5B,QAAI,iBAAiB,OAAO,KAAK,GAAG;AAClC,aAAO,EAAE,iBAAiB,wBAAA;AAAA,IAC5B;AAEA,WAAO,EAAE,iBAAiB,qBAAA;AAAA,EAC5B;AAEA,QAAM,iBAAiB,MAAc;AACnC,QAAI,UAAU;AACZ,UAAI,gBAAgB,WAAW,EAAG,QAAO;AACzC,UAAI,gBAAgB,WAAW,EAAG,QAAO,gBAAgB,CAAC,EAAE;AAC5D,aAAO,GAAG,gBAAgB,MAAM;AAAA,IAClC;AACA,WAAO,iBAAiB,eAAe,QAAQ;AAAA,EACjD;AAEA,SACE,qBAAC,OAAA,EAAI,WAAU,YAAW,KAAK,aAC7B,UAAA;AAAA,IAAA;AAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA,OACE,WACI,MAAM,QAAQ,KAAK,IACjB,MAAM,IAAI,MAAM,IAChB,CAAA,IACF,UAAU,UAAa,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK,IAC3D,OAAO,KAAK,IACZ;AAAA,QAGR,UAAU,MAAM;AAAA,QAAC;AAAA,QACjB,WAAU;AAAA,QACV;AAAA,QACA,UAAU;AAAA,QACV;AAAA,QAEC,kBAAQ,IAAI,CAAC,WACZ,oBAAC,YAA0B,OAAO,OAAO,OAAO,UAAU,OAAO,UAC9D,UAAA,OAAO,MAAA,GADG,OAAO,KAEpB,CACD;AAAA,MAAA;AAAA,IAAA;AAAA,IAGH;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,WAAW;AAAA,QACX,SAAS;AAAA,QACT,MAAK;AAAA,QACL,iBAAe;AAAA,QACf,iBAAc;AAAA,QACd,UAAU,WAAW,KAAK;AAAA,QAC1B,OAAO;AAAA,UACL,GAAG,kBAAA;AAAA,UACH,GAAG,kBAAA;AAAA,QAAkB;AAAA,QAEvB,cAAc,CAAC,MAAM;AACnB,cAAI,CAAC,YAAY,CAAC,OAAO;AACvB,cAAE,cAAc,MAAM,cAAc;AAAA,UACtC;AAAA,QACF;AAAA,QACA,cAAc,CAAC,MAAM;AACnB,cAAI,CAAC,YAAY,CAAC,OAAO;AACvB,cAAE,cAAc,MAAM,cAAc;AAAA,UACtC;AAAA,QACF;AAAA,QACA,SAAS,CAAC,MAAM;AACd,cAAI,CAAC,UAAU;AACb,cAAE,cAAc,MAAM,cAAc,QAChC,wBACA;AAAA,UACN;AAAA,QACF;AAAA,QACA,QAAQ,CAAC,MAAM;AACb,cAAI,CAAC,UAAU;AACb,cAAE,cAAc,MAAM,cAAc,QAChC,wBACA;AAAA,UACN;AAAA,QACF;AAAA,QACA,WAAW,CAAC,MAAM;AAChB,cAAI,EAAE,QAAQ,WAAW,EAAE,QAAQ,KAAK;AACtC,cAAE,eAAA;AACF,2BAAA;AAAA,UACF;AAAA,QACF;AAAA,QAEA,UAAA;AAAA,UAAA;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,OAAO;AAAA,gBACL,OACG,YAAY,gBAAgB,SAAS,KAAM,iBACxC,2BACA;AAAA,cAAA;AAAA,cAGP,UAAA,eAAA;AAAA,YAAe;AAAA,UAAA;AAAA,UAElB;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,WAAW,qCAAqC,SAAS,eAAe,EAAE;AAAA,cAC1E,OAAO,cAAA;AAAA,cAEP,8BAAC,iBAAA,CAAA,CAAgB;AAAA,YAAA;AAAA,UAAA;AAAA,QACnB;AAAA,MAAA;AAAA,IAAA;AAAA,IAGD,UACC;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,WAAW,kEAAkE,qBAAqB,IAAI,EAAE,SAAS;AAAA,QACjH,OAAO;AAAA,UACL,GAAG,kBAAA;AAAA,UACH,KAAK;AAAA,QAAA;AAAA,QAGN,UAAA,QAAQ,IAAI,CAAC,QAAQ,UACpB;AAAA,UAAC;AAAA,UAAA;AAAA,YAEC,WAAW;AAAA,cACT,qBAAqB,IAAI,EAAE;AAAA,cAC3B,qBAAqB,IAAI,EAAE;AAAA,cAC3B;AAAA,cACA,OAAO,YAAY;AAAA,cACnB,UAAU,KAAK;AAAA,cACf,UAAU,QAAQ,SAAS,KAAK;AAAA,cAChC,QAAQ,KAAK;AAAA,YAAA;AAAA,YAEf,OAAO;AAAA,cACL,GAAG,gBAAgB,MAAM;AAAA,cACzB,gBAAgB,QAAQ,IAAI,2BAA2B;AAAA,YAAA;AAAA,YAEzD,cAAc,CAAC,MAAM;AACnB,kBAAI,CAAC,OAAO,UAAU;AACpB,uBAAO,OAAO,EAAE,cAAc,OAAO,qBAAqB,MAAM,CAAC;AAAA,cACnE;AAAA,YACF;AAAA,YACA,cAAc,CAAC,MAAM;AACnB,kBAAI,CAAC,OAAO,UAAU;AACpB,uBAAO,OAAO,EAAE,cAAc,OAAO,gBAAgB,MAAM,CAAC;AAAA,cAC9D;AAAA,YACF;AAAA,YACA,SAAS,MAAM,aAAa,MAAM;AAAA,YAClC,MAAK;AAAA,YACL,iBAAe,iBAAiB,OAAO,KAAK;AAAA,YAE5C,UAAA,qBAAC,OAAA,EAAI,WAAU,qCACZ,UAAA;AAAA,cAAA,YACC;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,MAAK;AAAA,kBACL,SAAS,iBAAiB,OAAO,KAAK;AAAA,kBAEtC,UAAU,MAAM;AAAA,kBAAC;AAAA,kBACjB,WAAU;AAAA,kBACV,OAAO,EAAE,aAAa,wBAAA;AAAA,kBACtB,SAAS,CAAC,MAAM,EAAE,gBAAA;AAAA,gBAAgB;AAAA,cAAA;AAAA,cAGtC,oBAAC,QAAA,EAAK,WAAU,mBAAmB,iBAAO,OAAM;AAAA,cAC/C,CAAC,YAAY,iBAAiB,OAAO,KAAK,KACzC,oBAAC,QAAA,EAAK,WAAU,iBAAgB,OAAO,EAAE,OAAO,2BAC9C,UAAA,oBAAC,aAAU,EAAA,CACb;AAAA,YAAA,EAAA,CAEJ;AAAA,UAAA;AAAA,UA9CK,OAAO;AAAA,QAAA,CAgDf;AAAA,MAAA;AAAA,IAAA;AAAA,IAIJ,gBAAgB,oBAAC,cAAA,EAAa,SAAS,cAAc,WAAU,OAAA,CAAO;AAAA,EAAA,GACzE;AAEJ;"}
@@ -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 SIZE_DROPDOWN_CONFIG = {
6
8
  xs: { maxHeight: "max-h-32", optionPadding: "px-3 py-1.5", optionTextSize: "text-xs" },
7
9
  sm: { maxHeight: "max-h-40", optionPadding: "px-3 py-2", optionTextSize: "text-xs" },
@@ -10,6 +12,8 @@ const SIZE_DROPDOWN_CONFIG = {
10
12
  xl: { maxHeight: "max-h-64", optionPadding: "px-5 py-3", optionTextSize: "text-base" },
11
13
  "2xl": { maxHeight: "max-h-72", optionPadding: "px-6 py-4", optionTextSize: "text-lg" }
12
14
  };
15
+ const ChevronDownIcon = () => /* @__PURE__ */ jsxRuntime.jsx("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 9l-7 7-7-7" }) });
16
+ const CheckIcon = () => /* @__PURE__ */ jsxRuntime.jsx("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 13l4 4L19 7" }) });
13
17
  const LMSelect = ({
14
18
  options,
15
19
  value,
@@ -79,13 +83,16 @@ const LMSelect = ({
79
83
  onDropdownVisibleChange == null ? void 0 : onDropdownVisibleChange(newIsOpen);
80
84
  }
81
85
  };
82
- const baseClassName = `
83
- w-full ${componentSizes.SIZE_SELECTOR_CONFIG[size].padding} ${componentSizes.SIZE_SELECTOR_CONFIG[size].height} ${componentSizes.SIZE_SELECTOR_CONFIG[size].fontSize}
84
- border rounded-xl
85
- cursor-pointer select-none
86
- flex items-center justify-between
87
- ${className}
88
- `.trim().replace(/\s+/g, " ");
86
+ const baseClassName = cn.cn(
87
+ "w-full",
88
+ componentSizes.SIZE_SELECTOR_CONFIG[size].padding,
89
+ componentSizes.SIZE_SELECTOR_CONFIG[size].height,
90
+ componentSizes.SIZE_SELECTOR_CONFIG[size].fontSize,
91
+ "border rounded-xl",
92
+ "cursor-pointer select-none",
93
+ "flex items-center justify-between",
94
+ className
95
+ );
89
96
  const getSelectorStyles = () => {
90
97
  const baseStyles = {
91
98
  backgroundColor: "var(--lm-bg-elevated)",
@@ -149,18 +156,6 @@ const LMSelect = ({
149
156
  }
150
157
  return selectedOption ? selectedOption.label : placeholder;
151
158
  };
152
- const ChevronDown = () => /* @__PURE__ */ jsxRuntime.jsx(
153
- "svg",
154
- {
155
- className: `w-4 h-4 transition-transform duration-200 ${isOpen ? "rotate-180" : ""}`,
156
- fill: "none",
157
- stroke: "currentColor",
158
- viewBox: "0 0 24 24",
159
- style: getIconStyles(),
160
- children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 9l-7 7-7-7" })
161
- }
162
- );
163
- const CheckIcon = () => /* @__PURE__ */ jsxRuntime.jsx("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 13l4 4L19 7" }) });
164
159
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", ref: dropdownRef, children: [
165
160
  /* @__PURE__ */ jsxRuntime.jsx(
166
161
  "select",
@@ -181,7 +176,9 @@ const LMSelect = ({
181
176
  {
182
177
  className: baseClassName,
183
178
  onClick: toggleDropdown,
184
- role: "button",
179
+ role: "combobox",
180
+ "aria-expanded": isOpen,
181
+ "aria-haspopup": "listbox",
185
182
  tabIndex: disabled ? -1 : 0,
186
183
  style: {
187
184
  ...getSelectorStyles(),
@@ -223,13 +220,21 @@ const LMSelect = ({
223
220
  children: getDisplayText()
224
221
  }
225
222
  ),
226
- /* @__PURE__ */ jsxRuntime.jsx(ChevronDown, {})
223
+ /* @__PURE__ */ jsxRuntime.jsx(
224
+ "span",
225
+ {
226
+ className: `transition-transform duration-200 ${isOpen ? "rotate-180" : ""}`,
227
+ style: getIconStyles(),
228
+ children: /* @__PURE__ */ jsxRuntime.jsx(ChevronDownIcon, {})
229
+ }
230
+ )
227
231
  ]
228
232
  }
229
233
  ),
230
234
  isOpen && /* @__PURE__ */ jsxRuntime.jsx(
231
235
  "div",
232
236
  {
237
+ role: "listbox",
233
238
  className: `absolute left-0 right-0 z-50 border rounded-xl overflow-y-auto ${SIZE_DROPDOWN_CONFIG[size].maxHeight}`,
234
239
  style: {
235
240
  ...getDropdownStyles(),
@@ -238,14 +243,15 @@ const LMSelect = ({
238
243
  children: options.map((option, index) => /* @__PURE__ */ jsxRuntime.jsx(
239
244
  "div",
240
245
  {
241
- className: `
242
- ${SIZE_DROPDOWN_CONFIG[size].optionPadding} ${SIZE_DROPDOWN_CONFIG[size].optionTextSize} font-medium
243
- cursor-pointer transition-all duration-150
244
- ${option.disabled ? "cursor-not-allowed" : ""}
245
- ${index === 0 ? "rounded-t-xl" : ""}
246
- ${index === options.length - 1 ? "rounded-b-xl" : ""}
247
- ${index > 0 ? "border-t" : ""}
248
- `,
246
+ className: cn.cn(
247
+ SIZE_DROPDOWN_CONFIG[size].optionPadding,
248
+ SIZE_DROPDOWN_CONFIG[size].optionTextSize,
249
+ "font-medium cursor-pointer transition-all duration-150",
250
+ option.disabled && "cursor-not-allowed",
251
+ index === 0 && "rounded-t-xl",
252
+ index === options.length - 1 && "rounded-b-xl",
253
+ index > 0 && "border-t"
254
+ ),
249
255
  style: {
250
256
  ...getOptionStyles(option),
251
257
  borderTopColor: index > 0 ? "var(--lm-border-light)" : "transparent"
@@ -284,25 +290,8 @@ const LMSelect = ({
284
290
  ))
285
291
  }
286
292
  ),
287
- errorMessage && /* @__PURE__ */ jsxRuntime.jsxs(
288
- "p",
289
- {
290
- className: "text-xs flex items-center gap-1 mt-2",
291
- style: { color: "var(--lm-error-500)" },
292
- children: [
293
- /* @__PURE__ */ jsxRuntime.jsx("svg", { className: "w-3 h-3", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ jsxRuntime.jsx(
294
- "path",
295
- {
296
- fillRule: "evenodd",
297
- 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",
298
- clipRule: "evenodd"
299
- }
300
- ) }),
301
- errorMessage
302
- ]
303
- }
304
- )
293
+ errorMessage && /* @__PURE__ */ jsxRuntime.jsx(ErrorMessage.ErrorMessage, { message: errorMessage, className: "mt-2" })
305
294
  ] });
306
295
  };
307
296
  exports.LMSelect = LMSelect;
308
- //# sourceMappingURL=LMSelect-ByQcUp2S.cjs.map
297
+ //# sourceMappingURL=LMSelect-xIVolEhx.cjs.map