@ryanhe919/lumen-ui 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js ADDED
@@ -0,0 +1,3847 @@
1
+ import { jsx, jsxs, Fragment } from "react/jsx-runtime";
2
+ import React, { memo, useRef, useState, useEffect, useCallback, useId, useMemo } from "react";
3
+ import { createPortal } from "react-dom";
4
+ const COMPONENT_SIZE_ORDER = [
5
+ "xs",
6
+ "sm",
7
+ "md",
8
+ "lg",
9
+ "xl",
10
+ "2xl"
11
+ ];
12
+ const SIZE_TEXT_CLASSES = {
13
+ xs: "text-xs",
14
+ sm: "text-sm",
15
+ md: "text-base",
16
+ lg: "text-lg",
17
+ xl: "text-xl",
18
+ "2xl": "text-2xl"
19
+ };
20
+ const SIZE_HEADING_CLASSES = {
21
+ xs: "text-lg",
22
+ sm: "text-xl",
23
+ md: "text-2xl",
24
+ lg: "text-3xl",
25
+ xl: "text-4xl",
26
+ "2xl": "text-5xl"
27
+ };
28
+ const SIZE_DISPLAY_CLASSES = {
29
+ xs: "text-xl",
30
+ sm: "text-2xl",
31
+ md: "text-3xl",
32
+ lg: "text-4xl",
33
+ xl: "text-5xl",
34
+ "2xl": "text-6xl"
35
+ };
36
+ const SIZE_GAP_CLASSES = {
37
+ xs: "gap-1",
38
+ sm: "gap-1.5",
39
+ md: "gap-2",
40
+ lg: "gap-2.5",
41
+ xl: "gap-3",
42
+ "2xl": "gap-4"
43
+ };
44
+ const SIZE_PADDING_CLASSES = {
45
+ xs: "p-3",
46
+ sm: "p-4",
47
+ md: "p-6",
48
+ lg: "p-8",
49
+ xl: "p-10",
50
+ "2xl": "p-12"
51
+ };
52
+ const SIZE_BUTTON_CONFIG = {
53
+ xs: { padding: "px-2.5 py-1.5", height: "h-7" },
54
+ sm: { padding: "px-3 py-2", height: "h-8" },
55
+ md: { padding: "px-4 py-2.5", height: "h-10" },
56
+ lg: { padding: "px-5 py-3", height: "h-12" },
57
+ xl: { padding: "px-6 py-3.5", height: "h-14" },
58
+ "2xl": { padding: "px-8 py-4", height: "h-16" }
59
+ };
60
+ const SIZE_INPUT_CONFIG = {
61
+ xs: { padding: "px-3 py-1", height: "h-7", fontSize: "text-xs" },
62
+ sm: { padding: "px-3 py-1.5", height: "h-9", fontSize: "text-sm" },
63
+ md: { padding: "px-4 py-2", height: "h-10", fontSize: "text-sm" },
64
+ lg: { padding: "px-4 py-2.5", height: "h-12", fontSize: "text-base" },
65
+ xl: { padding: "px-5 py-3", height: "h-14", fontSize: "text-base" },
66
+ "2xl": { padding: "px-6 py-4", height: "h-16", fontSize: "text-lg" }
67
+ };
68
+ const SIZE_SELECTOR_CONFIG = {
69
+ xs: { padding: "px-3 py-1", height: "h-7", fontSize: "text-xs" },
70
+ sm: { padding: "px-3 py-1.5", height: "h-9", fontSize: "text-sm" },
71
+ md: { padding: "px-4 py-2", height: "h-10", fontSize: "text-sm" },
72
+ lg: { padding: "px-4 py-2.5", height: "h-12", fontSize: "text-base" },
73
+ xl: { padding: "px-5 py-3", height: "h-14", fontSize: "text-base" },
74
+ "2xl": { padding: "px-6 py-4", height: "h-16", fontSize: "text-lg" }
75
+ };
76
+ const SIZE_MODAL_CONFIG = {
77
+ xs: { width: "360px", maxWidth: "90vw" },
78
+ sm: { width: "480px", maxWidth: "90vw" },
79
+ md: { width: "640px", maxWidth: "90vw" },
80
+ lg: { width: "800px", maxWidth: "95vw" },
81
+ xl: { width: "960px", maxWidth: "95vw" },
82
+ "2xl": { width: "1200px", maxWidth: "95vw" }
83
+ };
84
+ const SIZE_TOOLTIP_CONFIG = {
85
+ xs: { paddingClass: "px-2.5 py-1.5", textClass: "text-xs", maxWidth: 200 },
86
+ sm: { paddingClass: "px-3 py-2", textClass: "text-sm", maxWidth: 240 },
87
+ md: { paddingClass: "px-4 py-2.5", textClass: "text-sm", maxWidth: 300 },
88
+ lg: { paddingClass: "px-4 py-3", textClass: "text-base", maxWidth: 360 },
89
+ xl: { paddingClass: "px-5 py-3", textClass: "text-lg", maxWidth: 420 },
90
+ "2xl": { paddingClass: "px-6 py-4", textClass: "text-xl", maxWidth: 500 }
91
+ };
92
+ const SIZE_ICON_CONFIG = {
93
+ xs: "w-4 h-4",
94
+ sm: "w-5 h-5",
95
+ md: "w-6 h-6",
96
+ lg: "w-8 h-8",
97
+ xl: "w-10 h-10",
98
+ "2xl": "w-12 h-12"
99
+ };
100
+ const SIZE_TABLE_CONFIG = {
101
+ xs: { cellPadding: "px-2 py-1", rowHeight: "h-8" },
102
+ sm: { cellPadding: "px-3 py-1.5", rowHeight: "h-10" },
103
+ md: { cellPadding: "px-4 py-2", rowHeight: "h-12" },
104
+ lg: { cellPadding: "px-6 py-3", rowHeight: "h-14" },
105
+ xl: { cellPadding: "px-8 py-4", rowHeight: "h-16" },
106
+ "2xl": { cellPadding: "px-10 py-5", rowHeight: "h-20" }
107
+ };
108
+ const clampComponentSize = (size, allowedSizes, fallback = "md") => {
109
+ const nextSize = size ?? fallback;
110
+ return allowedSizes.includes(nextSize) ? nextSize : fallback;
111
+ };
112
+ const LMButton = ({
113
+ children,
114
+ variant = "primary",
115
+ size = "md",
116
+ loading = false,
117
+ loadingText,
118
+ leftIcon,
119
+ rightIcon,
120
+ fullWidth = false,
121
+ rounded = false,
122
+ disabled = false,
123
+ className = "",
124
+ ...props
125
+ }) => {
126
+ const isDisabled = disabled || loading;
127
+ const resolvedSize = clampComponentSize(size, COMPONENT_SIZE_ORDER);
128
+ const roundedClasses = rounded ? "rounded-full" : "rounded-2xl";
129
+ const widthClasses = fullWidth ? "w-full" : "";
130
+ const baseClassName = `
131
+ ${SIZE_BUTTON_CONFIG[resolvedSize].padding} ${SIZE_TEXT_CLASSES[resolvedSize]} ${SIZE_GAP_CLASSES[resolvedSize]}
132
+ ${roundedClasses} ${widthClasses}
133
+ backdrop-blur-md border transition-all duration-300
134
+ shadow-sm font-medium focus:ring-2 focus:ring-offset-0
135
+ focus:outline-none disabled:cursor-not-allowed
136
+ flex items-center justify-center
137
+ ${className}
138
+ `.trim().replace(/\s+/g, " ");
139
+ const getButtonStyles = () => {
140
+ const baseStyles = {
141
+ backgroundColor: "var(--lm-bg-elevated)",
142
+ color: "var(--lm-text-primary)",
143
+ borderColor: "var(--lm-border-default)",
144
+ boxShadow: "var(--lm-shadow-sm)"
145
+ };
146
+ switch (variant) {
147
+ case "primary":
148
+ return {
149
+ ...baseStyles,
150
+ backgroundColor: "var(--lm-primary-500)",
151
+ color: "white",
152
+ borderColor: "var(--lm-primary-500)",
153
+ "--tw-ring-color": "var(--lm-primary-400)",
154
+ "--tw-ring-opacity": "0.3"
155
+ };
156
+ case "secondary":
157
+ return {
158
+ ...baseStyles,
159
+ backgroundColor: "var(--lm-bg-paper)",
160
+ color: "var(--lm-text-primary)",
161
+ borderColor: "var(--lm-border-default)",
162
+ "--tw-ring-color": "var(--lm-primary-400)",
163
+ "--tw-ring-opacity": "0.3"
164
+ };
165
+ case "outline":
166
+ return {
167
+ ...baseStyles,
168
+ backgroundColor: "transparent",
169
+ color: "var(--lm-primary-600)",
170
+ borderColor: "var(--lm-primary-300)",
171
+ "--tw-ring-color": "var(--lm-primary-400)",
172
+ "--tw-ring-opacity": "0.3"
173
+ };
174
+ case "ghost":
175
+ return {
176
+ ...baseStyles,
177
+ backgroundColor: "transparent",
178
+ color: "var(--lm-text-primary)",
179
+ borderColor: "transparent",
180
+ "--tw-ring-color": "var(--lm-primary-400)",
181
+ "--tw-ring-opacity": "0.3"
182
+ };
183
+ case "danger":
184
+ return {
185
+ ...baseStyles,
186
+ backgroundColor: "var(--lm-error-500)",
187
+ color: "white",
188
+ borderColor: "var(--lm-error-500)",
189
+ "--tw-ring-color": "var(--lm-error-400)",
190
+ "--tw-ring-opacity": "0.3"
191
+ };
192
+ case "success":
193
+ return {
194
+ ...baseStyles,
195
+ backgroundColor: "var(--lm-success-500)",
196
+ color: "white",
197
+ borderColor: "var(--lm-success-500)",
198
+ "--tw-ring-color": "var(--lm-success-400)",
199
+ "--tw-ring-opacity": "0.3"
200
+ };
201
+ case "warning":
202
+ return {
203
+ ...baseStyles,
204
+ backgroundColor: "var(--lm-warning-500)",
205
+ color: "white",
206
+ borderColor: "var(--lm-warning-500)",
207
+ "--tw-ring-color": "var(--lm-warning-400)",
208
+ "--tw-ring-opacity": "0.3"
209
+ };
210
+ default:
211
+ return baseStyles;
212
+ }
213
+ };
214
+ const getDisabledStyles = () => {
215
+ if (isDisabled) {
216
+ return {
217
+ backgroundColor: "var(--lm-bg-paper)",
218
+ color: "var(--lm-text-disabled)",
219
+ borderColor: "var(--lm-border-light)",
220
+ cursor: "not-allowed",
221
+ opacity: 0.6
222
+ };
223
+ }
224
+ return {};
225
+ };
226
+ const getHoverStyles = () => {
227
+ if (isDisabled) return {};
228
+ switch (variant) {
229
+ case "primary":
230
+ return {
231
+ backgroundColor: "var(--lm-primary-600)",
232
+ borderColor: "var(--lm-primary-600)"
233
+ };
234
+ case "secondary":
235
+ return {
236
+ backgroundColor: "var(--lm-bg-elevated)",
237
+ borderColor: "var(--lm-border-strong)"
238
+ };
239
+ case "outline":
240
+ return {
241
+ backgroundColor: "var(--lm-primary-50)",
242
+ borderColor: "var(--lm-primary-400)"
243
+ };
244
+ case "ghost":
245
+ return {
246
+ backgroundColor: "var(--lm-bg-paper)"
247
+ };
248
+ case "danger":
249
+ return {
250
+ backgroundColor: "var(--lm-error-600)",
251
+ borderColor: "var(--lm-error-600)"
252
+ };
253
+ case "success":
254
+ return {
255
+ backgroundColor: "var(--lm-success-600)",
256
+ borderColor: "var(--lm-success-600)"
257
+ };
258
+ case "warning":
259
+ return {
260
+ backgroundColor: "var(--lm-warning-600)",
261
+ borderColor: "var(--lm-warning-600)"
262
+ };
263
+ default:
264
+ return {};
265
+ }
266
+ };
267
+ const getActiveStyles = () => {
268
+ if (isDisabled) return {};
269
+ switch (variant) {
270
+ case "primary":
271
+ return {
272
+ backgroundColor: "var(--lm-primary-700)",
273
+ borderColor: "var(--lm-primary-700)"
274
+ };
275
+ case "secondary":
276
+ return {
277
+ backgroundColor: "var(--lm-bg-paper)",
278
+ borderColor: "var(--lm-border-default)"
279
+ };
280
+ case "outline":
281
+ return {
282
+ backgroundColor: "var(--lm-primary-100)",
283
+ borderColor: "var(--lm-primary-500)"
284
+ };
285
+ case "ghost":
286
+ return {
287
+ backgroundColor: "var(--lm-bg-elevated)"
288
+ };
289
+ case "danger":
290
+ return {
291
+ backgroundColor: "var(--lm-error-700)",
292
+ borderColor: "var(--lm-error-700)"
293
+ };
294
+ case "success":
295
+ return {
296
+ backgroundColor: "var(--lm-success-700)",
297
+ borderColor: "var(--lm-success-700)"
298
+ };
299
+ case "warning":
300
+ return {
301
+ backgroundColor: "var(--lm-warning-700)",
302
+ borderColor: "var(--lm-warning-700)"
303
+ };
304
+ default:
305
+ return {};
306
+ }
307
+ };
308
+ const getIconStyles = () => {
309
+ if (isDisabled) {
310
+ return { color: "var(--lm-text-disabled)" };
311
+ }
312
+ switch (variant) {
313
+ case "primary":
314
+ case "danger":
315
+ case "success":
316
+ case "warning":
317
+ return { color: "white" };
318
+ case "outline":
319
+ return { color: "var(--lm-primary-600)" };
320
+ default:
321
+ return { color: "var(--lm-text-primary)" };
322
+ }
323
+ };
324
+ const LoadingSpinner = () => /* @__PURE__ */ jsxs(
325
+ "svg",
326
+ {
327
+ className: "animate-spin h-4 w-4",
328
+ xmlns: "http://www.w3.org/2000/svg",
329
+ fill: "none",
330
+ viewBox: "0 0 24 24",
331
+ style: getIconStyles(),
332
+ children: [
333
+ /* @__PURE__ */ jsx(
334
+ "circle",
335
+ {
336
+ className: "opacity-25",
337
+ cx: "12",
338
+ cy: "12",
339
+ r: "10",
340
+ stroke: "currentColor",
341
+ strokeWidth: "4"
342
+ }
343
+ ),
344
+ /* @__PURE__ */ jsx(
345
+ "path",
346
+ {
347
+ className: "opacity-75",
348
+ fill: "currentColor",
349
+ d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
350
+ }
351
+ )
352
+ ]
353
+ }
354
+ );
355
+ return /* @__PURE__ */ jsx(
356
+ "button",
357
+ {
358
+ ...props,
359
+ disabled: isDisabled,
360
+ className: baseClassName,
361
+ style: {
362
+ ...getButtonStyles(),
363
+ ...getDisabledStyles()
364
+ },
365
+ onMouseEnter: (e) => {
366
+ var _a;
367
+ if (!isDisabled) Object.assign(e.currentTarget.style, getHoverStyles());
368
+ (_a = props.onMouseEnter) == null ? void 0 : _a.call(props, e);
369
+ },
370
+ onMouseLeave: (e) => {
371
+ var _a;
372
+ if (!isDisabled)
373
+ Object.assign(e.currentTarget.style, {
374
+ ...getButtonStyles(),
375
+ ...getDisabledStyles()
376
+ });
377
+ (_a = props.onMouseLeave) == null ? void 0 : _a.call(props, e);
378
+ },
379
+ onMouseDown: (e) => {
380
+ var _a;
381
+ if (!isDisabled) Object.assign(e.currentTarget.style, getActiveStyles());
382
+ (_a = props.onMouseDown) == null ? void 0 : _a.call(props, e);
383
+ },
384
+ onMouseUp: (e) => {
385
+ var _a;
386
+ if (!isDisabled) Object.assign(e.currentTarget.style, getHoverStyles());
387
+ (_a = props.onMouseUp) == null ? void 0 : _a.call(props, e);
388
+ },
389
+ onFocus: (e) => {
390
+ var _a;
391
+ if (!isDisabled) {
392
+ e.currentTarget.style.borderColor = "var(--lm-primary-400)";
393
+ }
394
+ (_a = props.onFocus) == null ? void 0 : _a.call(props, e);
395
+ },
396
+ onBlur: (e) => {
397
+ var _a;
398
+ if (!isDisabled)
399
+ Object.assign(e.currentTarget.style, {
400
+ ...getButtonStyles(),
401
+ ...getDisabledStyles()
402
+ });
403
+ (_a = props.onBlur) == null ? void 0 : _a.call(props, e);
404
+ },
405
+ children: loading ? /* @__PURE__ */ jsxs(Fragment, { children: [
406
+ /* @__PURE__ */ jsx(LoadingSpinner, {}),
407
+ loadingText || children
408
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
409
+ leftIcon && /* @__PURE__ */ jsx("span", { style: getIconStyles(), children: leftIcon }),
410
+ /* @__PURE__ */ jsx("span", { className: "inline-flex items-center", children }),
411
+ rightIcon && /* @__PURE__ */ jsx("span", { style: getIconStyles(), children: rightIcon })
412
+ ] })
413
+ }
414
+ );
415
+ };
416
+ const LMButton$1 = memo(LMButton);
417
+ const LMInput = ({
418
+ leftIcon,
419
+ rightElement,
420
+ error = false,
421
+ errorMessage,
422
+ className = "",
423
+ size = "md",
424
+ includeSeconds = false,
425
+ ...props
426
+ }) => {
427
+ const hasLeftIcon = !!leftIcon;
428
+ const hasRightElement = !!rightElement;
429
+ const errorId = useRef(
430
+ `lm-input-err-${Math.random().toString(36).slice(2)}`
431
+ ).current;
432
+ const timeInputProps = () => {
433
+ if ((props.type === "datetime-local" || props.type === "time") && includeSeconds) {
434
+ return { step: "1" };
435
+ }
436
+ return {};
437
+ };
438
+ const baseClassName = `
439
+ w-full ${SIZE_INPUT_CONFIG[size].padding} ${SIZE_INPUT_CONFIG[size].height} ${SIZE_INPUT_CONFIG[size].fontSize}
440
+ backdrop-blur-md border rounded-2xl
441
+ focus:ring-2 focus:outline-none transition-all duration-300
442
+ shadow-sm
443
+ ${hasLeftIcon ? "pl-10" : ""}
444
+ ${hasRightElement ? "pr-10" : ""}
445
+ ${className}
446
+ `.trim().replace(/\s+/g, " ");
447
+ const getInputStyles = () => {
448
+ const baseStyles = {
449
+ backgroundColor: "var(--lm-bg-elevated)",
450
+ color: "var(--lm-text-primary)",
451
+ borderColor: error ? "var(--lm-error-300)" : "var(--lm-border-default)",
452
+ boxShadow: "var(--lm-shadow-sm)"
453
+ };
454
+ return {
455
+ ...baseStyles,
456
+ "--tw-ring-color": error ? "var(--lm-error-400)" : "var(--lm-primary-400)",
457
+ "--tw-ring-opacity": "0.3"
458
+ };
459
+ };
460
+ const getDisabledStyles = () => props.disabled ? {
461
+ backgroundColor: "var(--lm-bg-paper)",
462
+ color: "var(--lm-text-disabled)",
463
+ cursor: "not-allowed",
464
+ opacity: 0.6
465
+ } : {};
466
+ const getIconStyles = () => error ? { color: "var(--lm-error-400)" } : { color: "var(--lm-text-secondary)" };
467
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
468
+ /* @__PURE__ */ jsxs("div", { className: "relative group", children: [
469
+ hasLeftIcon && /* @__PURE__ */ jsx("div", { className: "absolute inset-y-0 left-0 pl-4 flex items-center pointer-events-none z-10", children: /* @__PURE__ */ jsx(
470
+ "div",
471
+ {
472
+ className: "transition-colors duration-200",
473
+ style: getIconStyles(),
474
+ children: leftIcon
475
+ }
476
+ ) }),
477
+ /* @__PURE__ */ jsx(
478
+ "input",
479
+ {
480
+ ...props,
481
+ ...timeInputProps(),
482
+ className: baseClassName,
483
+ "aria-invalid": error || void 0,
484
+ "aria-describedby": errorMessage ? errorId : void 0,
485
+ style: {
486
+ ...getInputStyles(),
487
+ ...getDisabledStyles()
488
+ },
489
+ onMouseEnter: (e) => {
490
+ var _a;
491
+ if (!props.disabled && !error) {
492
+ e.currentTarget.style.borderColor = "var(--lm-border-strong)";
493
+ }
494
+ (_a = props.onMouseEnter) == null ? void 0 : _a.call(props, e);
495
+ },
496
+ onMouseLeave: (e) => {
497
+ var _a;
498
+ if (!props.disabled && !error) {
499
+ e.currentTarget.style.borderColor = "var(--lm-border-default)";
500
+ }
501
+ (_a = props.onMouseLeave) == null ? void 0 : _a.call(props, e);
502
+ },
503
+ onFocus: (e) => {
504
+ var _a;
505
+ if (!props.disabled) {
506
+ e.currentTarget.style.borderColor = error ? "var(--lm-error-400)" : "var(--lm-primary-400)";
507
+ }
508
+ (_a = props.onFocus) == null ? void 0 : _a.call(props, e);
509
+ },
510
+ onBlur: (e) => {
511
+ var _a;
512
+ if (!props.disabled) {
513
+ e.currentTarget.style.borderColor = error ? "var(--lm-error-300)" : "var(--lm-border-default)";
514
+ }
515
+ (_a = props.onBlur) == null ? void 0 : _a.call(props, e);
516
+ }
517
+ }
518
+ ),
519
+ hasRightElement && /* @__PURE__ */ jsx("div", { className: "absolute inset-y-0 right-0 pr-4 flex items-center z-10", children: rightElement })
520
+ ] }),
521
+ errorMessage && /* @__PURE__ */ jsxs(
522
+ "p",
523
+ {
524
+ id: errorId,
525
+ className: "text-xs flex items-center gap-1",
526
+ style: { color: "var(--lm-error-500)" },
527
+ role: "alert",
528
+ "aria-live": "polite",
529
+ children: [
530
+ /* @__PURE__ */ jsx(
531
+ "svg",
532
+ {
533
+ className: "w-3 h-3",
534
+ fill: "currentColor",
535
+ viewBox: "0 0 20 20",
536
+ "aria-hidden": "true",
537
+ children: /* @__PURE__ */ jsx(
538
+ "path",
539
+ {
540
+ fillRule: "evenodd",
541
+ 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",
542
+ clipRule: "evenodd"
543
+ }
544
+ )
545
+ }
546
+ ),
547
+ errorMessage
548
+ ]
549
+ }
550
+ )
551
+ ] });
552
+ };
553
+ const sizeConfig$3 = {
554
+ xs: {
555
+ padding: "px-2 py-0.5",
556
+ fontSize: "text-xs",
557
+ dotSize: "w-1.5 h-1.5",
558
+ iconSize: "text-xs"
559
+ },
560
+ sm: {
561
+ padding: "px-3 py-1",
562
+ fontSize: "text-xs",
563
+ dotSize: "w-2 h-2",
564
+ iconSize: "text-xs"
565
+ },
566
+ md: {
567
+ padding: "px-3.5 py-1.5",
568
+ fontSize: "text-sm",
569
+ dotSize: "w-2 h-2",
570
+ iconSize: "text-sm"
571
+ },
572
+ lg: {
573
+ padding: "px-4 py-2",
574
+ fontSize: "text-sm",
575
+ dotSize: "w-2.5 h-2.5",
576
+ iconSize: "text-sm"
577
+ }
578
+ };
579
+ const LMBadge = ({
580
+ children,
581
+ variant = "primary",
582
+ size = "sm",
583
+ className = "",
584
+ dot = false,
585
+ icon
586
+ }) => {
587
+ const getVariantStyles = () => {
588
+ const variantMap = {
589
+ primary: {
590
+ backgroundColor: "var(--lm-primary-100)",
591
+ color: "var(--lm-primary-700)",
592
+ borderColor: "var(--lm-primary-200)"
593
+ },
594
+ secondary: {
595
+ backgroundColor: "var(--lm-gray-100)",
596
+ color: "var(--lm-gray-700)",
597
+ borderColor: "var(--lm-gray-200)"
598
+ },
599
+ success: {
600
+ backgroundColor: "var(--lm-success-100)",
601
+ color: "var(--lm-success-700)",
602
+ borderColor: "var(--lm-success-200)"
603
+ },
604
+ warning: {
605
+ backgroundColor: "var(--lm-warning-100)",
606
+ color: "var(--lm-warning-700)",
607
+ borderColor: "var(--lm-warning-200)"
608
+ },
609
+ error: {
610
+ backgroundColor: "var(--lm-error-100)",
611
+ color: "var(--lm-error-700)",
612
+ borderColor: "var(--lm-error-200)"
613
+ },
614
+ info: {
615
+ backgroundColor: "var(--lm-info-100)",
616
+ color: "var(--lm-info-700)",
617
+ borderColor: "var(--lm-info-200)"
618
+ },
619
+ neutral: {
620
+ backgroundColor: "var(--lm-bg-elevated)",
621
+ color: "var(--lm-text-secondary)",
622
+ borderColor: "var(--lm-border-default)"
623
+ }
624
+ };
625
+ return variantMap[variant];
626
+ };
627
+ const getDotColor = () => {
628
+ const dotColorMap = {
629
+ primary: "var(--lm-primary-500)",
630
+ secondary: "var(--lm-gray-500)",
631
+ success: "var(--lm-success-500)",
632
+ warning: "var(--lm-warning-500)",
633
+ error: "var(--lm-error-500)",
634
+ info: "var(--lm-info-500)",
635
+ neutral: "var(--lm-text-disabled)"
636
+ };
637
+ return dotColorMap[variant];
638
+ };
639
+ const currentSize = sizeConfig$3[size];
640
+ return /* @__PURE__ */ jsxs(
641
+ "span",
642
+ {
643
+ className: `inline-flex items-center justify-center ${currentSize.padding} ${currentSize.fontSize} rounded-full border font-medium transition-all duration-200 ${className}`,
644
+ style: getVariantStyles(),
645
+ children: [
646
+ dot && /* @__PURE__ */ jsx(
647
+ "span",
648
+ {
649
+ className: `${currentSize.dotSize} rounded-full mr-1.5 flex-shrink-0`,
650
+ style: { backgroundColor: getDotColor() }
651
+ }
652
+ ),
653
+ icon && /* @__PURE__ */ jsx("span", { className: `${currentSize.iconSize} mr-1.5 flex-shrink-0`, children: icon }),
654
+ /* @__PURE__ */ jsx("span", { className: "truncate", children })
655
+ ]
656
+ }
657
+ );
658
+ };
659
+ const LMTooltip = ({
660
+ content,
661
+ children,
662
+ placement = "top",
663
+ maxWidth,
664
+ size = "sm"
665
+ }) => {
666
+ const [visible, setVisible] = useState(false);
667
+ const [position, setPosition] = useState({ top: 0, left: 0 });
668
+ const triggerRef = useRef(null);
669
+ const tooltipRef = useRef(null);
670
+ const resolvedSize = clampComponentSize(size, COMPONENT_SIZE_ORDER);
671
+ const effectiveMaxWidth = maxWidth ?? SIZE_TOOLTIP_CONFIG[resolvedSize].maxWidth;
672
+ useEffect(() => {
673
+ if (visible && triggerRef.current && tooltipRef.current) {
674
+ const triggerRect = triggerRef.current.getBoundingClientRect();
675
+ const tooltipRect = tooltipRef.current.getBoundingClientRect();
676
+ let top = 0;
677
+ let left = 0;
678
+ switch (placement) {
679
+ case "top":
680
+ top = triggerRect.top - tooltipRect.height - 8;
681
+ left = triggerRect.left + triggerRect.width / 2 - tooltipRect.width / 2;
682
+ break;
683
+ case "bottom":
684
+ top = triggerRect.bottom + 8;
685
+ left = triggerRect.left + triggerRect.width / 2 - tooltipRect.width / 2;
686
+ break;
687
+ case "left":
688
+ top = triggerRect.top + triggerRect.height / 2 - tooltipRect.height / 2;
689
+ left = triggerRect.left - tooltipRect.width - 8;
690
+ break;
691
+ case "right":
692
+ top = triggerRect.top + triggerRect.height / 2 - tooltipRect.height / 2;
693
+ left = triggerRect.right + 8;
694
+ break;
695
+ }
696
+ const padding = 8;
697
+ if (left < padding) left = padding;
698
+ if (left + tooltipRect.width > window.innerWidth - padding) {
699
+ left = window.innerWidth - tooltipRect.width - padding;
700
+ }
701
+ if (top < padding) top = padding;
702
+ if (top + tooltipRect.height > window.innerHeight - padding) {
703
+ top = window.innerHeight - tooltipRect.height - padding;
704
+ }
705
+ setPosition({ top, left });
706
+ }
707
+ }, [visible, placement]);
708
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
709
+ /* @__PURE__ */ jsx(
710
+ "div",
711
+ {
712
+ ref: triggerRef,
713
+ onMouseEnter: () => setVisible(true),
714
+ onMouseLeave: () => setVisible(false),
715
+ className: "inline-block",
716
+ children
717
+ }
718
+ ),
719
+ visible && /* @__PURE__ */ jsx(
720
+ "div",
721
+ {
722
+ ref: tooltipRef,
723
+ className: `fixed z-50 ${SIZE_TOOLTIP_CONFIG[resolvedSize].paddingClass} ${SIZE_TOOLTIP_CONFIG[resolvedSize].textClass} rounded-lg shadow-lg pointer-events-none`,
724
+ style: {
725
+ top: `${position.top}px`,
726
+ left: `${position.left}px`,
727
+ maxWidth: `${effectiveMaxWidth}px`,
728
+ backgroundColor: "var(--lm-bg-elevated)",
729
+ borderColor: "var(--lm-border-default)",
730
+ color: "var(--lm-text-primary)",
731
+ border: "1px solid"
732
+ },
733
+ children: content
734
+ }
735
+ )
736
+ ] });
737
+ };
738
+ const MODAL_FOOTER_SIZE_MAP = {
739
+ xs: "xs",
740
+ sm: "xs",
741
+ md: "sm",
742
+ lg: "md",
743
+ xl: "md",
744
+ "2xl": "lg"
745
+ };
746
+ const LMModal = ({
747
+ visible,
748
+ title,
749
+ children,
750
+ footer,
751
+ onClose,
752
+ onOk,
753
+ onCancel,
754
+ okText = "Confirm",
755
+ cancelText = "Cancel",
756
+ showOk = true,
757
+ showCancel = true,
758
+ okLoading = false,
759
+ cancelLoading = false,
760
+ mask = true,
761
+ maskClosable = false,
762
+ closable = true,
763
+ closeIcon,
764
+ headerIcon,
765
+ width,
766
+ height,
767
+ size = "md",
768
+ className = "",
769
+ style,
770
+ centered = true,
771
+ fullscreen = false,
772
+ animationDuration = 300,
773
+ animation = true
774
+ }) => {
775
+ const modalRef = useRef(null);
776
+ const backdropRef = useRef(null);
777
+ const resolvedSize = clampComponentSize(size, COMPONENT_SIZE_ORDER);
778
+ const footerButtonSize = MODAL_FOOTER_SIZE_MAP[resolvedSize];
779
+ const getModalStyles = () => {
780
+ const baseStyles = {
781
+ backgroundColor: "var(--lm-bg-elevated)",
782
+ color: "var(--lm-text-primary)",
783
+ borderColor: "var(--lm-border-default)",
784
+ boxShadow: "var(--lm-shadow-xl)",
785
+ borderRadius: "1rem",
786
+ border: "1px solid var(--lm-border-default)",
787
+ backdropFilter: "blur(10px)",
788
+ ...style
789
+ };
790
+ if (fullscreen) {
791
+ baseStyles.width = "100vw";
792
+ baseStyles.height = "100vh";
793
+ baseStyles.maxWidth = "100vw";
794
+ baseStyles.maxHeight = "100vh";
795
+ baseStyles.borderRadius = "0";
796
+ } else {
797
+ baseStyles.width = width ? typeof width === "number" ? `${width}px` : width : SIZE_MODAL_CONFIG[resolvedSize].width;
798
+ baseStyles.maxWidth = SIZE_MODAL_CONFIG[resolvedSize].maxWidth;
799
+ if (height) {
800
+ baseStyles.height = typeof height === "number" ? `${height}px` : height;
801
+ }
802
+ }
803
+ return baseStyles;
804
+ };
805
+ const getBackdropStyles = () => mask ? { backgroundColor: "rgba(0, 0, 0, 0.5)", backdropFilter: "blur(4px)" } : { backgroundColor: "transparent", backdropFilter: "none" };
806
+ const handleOk = () => onOk ? onOk() : onClose == null ? void 0 : onClose();
807
+ const handleCancel = useCallback(() => {
808
+ if (onCancel) onCancel();
809
+ else onClose == null ? void 0 : onClose();
810
+ }, [onCancel, onClose]);
811
+ const handleBackdropClick = (e) => {
812
+ if (maskClosable && e.target === backdropRef.current) handleCancel();
813
+ };
814
+ useEffect(() => {
815
+ const keyHandler = (e) => {
816
+ if (visible && e.key === "Escape") handleCancel();
817
+ };
818
+ if (visible) {
819
+ document.addEventListener("keydown", keyHandler);
820
+ document.body.style.overflow = "hidden";
821
+ }
822
+ return () => {
823
+ document.removeEventListener("keydown", keyHandler);
824
+ if (visible) document.body.style.overflow = "";
825
+ };
826
+ }, [visible, handleCancel]);
827
+ const CloseIcon = () => /* @__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: "M6 18L18 6M6 6l12 12" }) });
828
+ const WindowIcon = () => /* @__PURE__ */ jsx("svg", { className: "w-5 h-5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 6h16M4 12h16M4 18h16" }) });
829
+ const defaultFooter = /* @__PURE__ */ jsxs(
830
+ "div",
831
+ {
832
+ className: "flex items-center justify-end gap-3 px-6 py-4 border-t",
833
+ style: { borderColor: "var(--lm-border-default)" },
834
+ children: [
835
+ showCancel && /* @__PURE__ */ jsx(
836
+ LMButton$1,
837
+ {
838
+ variant: "secondary",
839
+ size: footerButtonSize,
840
+ onClick: handleCancel,
841
+ disabled: cancelLoading,
842
+ loading: cancelLoading,
843
+ children: cancelText
844
+ }
845
+ ),
846
+ showOk && /* @__PURE__ */ jsx(
847
+ LMButton$1,
848
+ {
849
+ variant: "primary",
850
+ size: footerButtonSize,
851
+ onClick: handleOk,
852
+ disabled: okLoading,
853
+ loading: okLoading,
854
+ children: okText
855
+ }
856
+ )
857
+ ]
858
+ }
859
+ );
860
+ const getAnimationClasses = () => {
861
+ if (!animation) return "";
862
+ const ms = animationDuration;
863
+ const durationClass = ms <= 150 ? "duration-150" : ms <= 200 ? "duration-200" : ms <= 300 ? "duration-300" : ms <= 500 ? "duration-500" : ms <= 700 ? "duration-700" : "duration-1000";
864
+ return `transition-all ${durationClass} ease-in-out`;
865
+ };
866
+ if (!visible) return null;
867
+ const modalContent = /* @__PURE__ */ jsx(
868
+ "div",
869
+ {
870
+ ref: backdropRef,
871
+ className: `fixed inset-0 z-50 flex ${centered ? "items-center" : "items-start pt-20"} justify-center ${getAnimationClasses()}`,
872
+ style: getBackdropStyles(),
873
+ onClick: handleBackdropClick,
874
+ children: /* @__PURE__ */ jsxs(
875
+ "div",
876
+ {
877
+ ref: modalRef,
878
+ className: `relative ${getAnimationClasses()} ${className}`,
879
+ style: getModalStyles(),
880
+ onClick: (e) => e.stopPropagation(),
881
+ children: [
882
+ (title || closable) && /* @__PURE__ */ jsxs(
883
+ "div",
884
+ {
885
+ className: "flex items-center justify-between p-6 pb-4 border-b",
886
+ style: { borderColor: "var(--lm-border-default)" },
887
+ children: [
888
+ title && /* @__PURE__ */ jsxs(
889
+ "h3",
890
+ {
891
+ className: `font-bold flex items-center gap-2 ${SIZE_HEADING_CLASSES[resolvedSize]}`,
892
+ style: { color: "var(--lm-text-primary)" },
893
+ children: [
894
+ /* @__PURE__ */ jsx("span", { style: { color: "var(--lm-text-secondary)" }, children: headerIcon || /* @__PURE__ */ jsx(WindowIcon, {}) }),
895
+ title
896
+ ]
897
+ }
898
+ ),
899
+ closable && /* @__PURE__ */ jsx(
900
+ LMButton$1,
901
+ {
902
+ variant: "ghost",
903
+ size: "xs",
904
+ onClick: handleCancel,
905
+ leftIcon: closeIcon || /* @__PURE__ */ jsx(CloseIcon, {}),
906
+ className: "w-8 h-8 p-0",
907
+ "aria-label": "Close dialog",
908
+ title: "Close",
909
+ style: {
910
+ borderRadius: "0.5rem",
911
+ backgroundColor: "var(--lm-bg-paper)",
912
+ borderColor: "var(--lm-border-default)",
913
+ color: "var(--lm-text-secondary)"
914
+ }
915
+ }
916
+ )
917
+ ]
918
+ }
919
+ ),
920
+ /* @__PURE__ */ jsx("div", { className: "p-6", children }),
921
+ footer !== void 0 ? footer : showOk || showCancel ? defaultFooter : null
922
+ ]
923
+ }
924
+ )
925
+ }
926
+ );
927
+ return createPortal(modalContent, document.body);
928
+ };
929
+ const LMModal_default = memo(LMModal);
930
+ const sizeConfig$2 = {
931
+ xs: {
932
+ container: "p-2 gap-2",
933
+ label: "text-xs",
934
+ description: "text-xs mt-0.5",
935
+ errorMessage: "text-xs"
936
+ },
937
+ sm: {
938
+ container: "p-3 gap-2.5",
939
+ label: "text-sm",
940
+ description: "text-xs mt-1",
941
+ errorMessage: "text-xs"
942
+ },
943
+ md: {
944
+ container: "p-4 gap-3",
945
+ label: "text-base",
946
+ description: "text-sm mt-1",
947
+ errorMessage: "text-xs"
948
+ },
949
+ lg: {
950
+ container: "p-5 gap-4",
951
+ label: "text-lg",
952
+ description: "text-base mt-1.5",
953
+ errorMessage: "text-sm"
954
+ },
955
+ xl: {
956
+ container: "p-6 gap-4",
957
+ label: "text-xl",
958
+ description: "text-lg mt-2",
959
+ errorMessage: "text-sm"
960
+ },
961
+ "2xl": {
962
+ container: "p-8 gap-5",
963
+ label: "text-2xl",
964
+ description: "text-xl mt-2.5",
965
+ errorMessage: "text-base"
966
+ }
967
+ };
968
+ const LMCheckbox = ({
969
+ label,
970
+ description,
971
+ error = false,
972
+ errorMessage,
973
+ size = "md",
974
+ className = "",
975
+ ...props
976
+ }) => {
977
+ const currentSize = sizeConfig$2[size];
978
+ const checkboxSizeClass = SIZE_ICON_CONFIG[size];
979
+ const getCheckboxStyles = () => {
980
+ const baseStyles = {
981
+ backgroundColor: "var(--lm-bg-elevated)",
982
+ borderColor: error ? "var(--lm-error-300)" : "var(--lm-border-default)",
983
+ color: "var(--lm-primary-500)"
984
+ };
985
+ return {
986
+ ...baseStyles,
987
+ "--tw-ring-color": error ? "var(--lm-error-400)" : "var(--lm-primary-400)",
988
+ "--tw-ring-opacity": "0.3"
989
+ };
990
+ };
991
+ const getDisabledStyles = () => {
992
+ if (props.disabled) {
993
+ return {
994
+ backgroundColor: "var(--lm-bg-paper)",
995
+ borderColor: "var(--lm-border-light)",
996
+ color: "var(--lm-text-disabled)",
997
+ cursor: "not-allowed",
998
+ opacity: 0.6
999
+ };
1000
+ }
1001
+ return {};
1002
+ };
1003
+ const getContainerStyles = () => ({
1004
+ backgroundColor: error ? "var(--lm-error-50)" : "var(--lm-bg-paper)"
1005
+ });
1006
+ const getHoverContainerStyles = () => ({
1007
+ backgroundColor: error ? "var(--lm-error-100)" : "var(--lm-bg-elevated)"
1008
+ });
1009
+ const getLabelStyles = () => {
1010
+ if (error)
1011
+ return { color: "var(--lm-error-700)" };
1012
+ if (props.disabled)
1013
+ return {
1014
+ color: "var(--lm-text-disabled)",
1015
+ cursor: "not-allowed"
1016
+ };
1017
+ return {
1018
+ color: "var(--lm-text-primary)",
1019
+ cursor: "pointer"
1020
+ };
1021
+ };
1022
+ const getDescriptionStyles = () => error ? { color: "var(--lm-error-600)" } : { color: "var(--lm-text-secondary)" };
1023
+ const checkboxClassName = `
1024
+ ${checkboxSizeClass} border-2 rounded-md
1025
+ focus:ring-2 focus:ring-offset-0
1026
+ transition-all duration-200
1027
+ ${className}
1028
+ `.trim().replace(/\s+/g, " ");
1029
+ return /* @__PURE__ */ jsxs("div", { children: [
1030
+ /* @__PURE__ */ jsxs(
1031
+ "label",
1032
+ {
1033
+ className: `flex items-center rounded-2xl transition-colors duration-200 ${currentSize.container} ${props.disabled ? "" : "cursor-pointer"}`,
1034
+ style: getContainerStyles(),
1035
+ onMouseEnter: (e) => {
1036
+ if (!props.disabled) {
1037
+ Object.assign(e.currentTarget.style, getHoverContainerStyles());
1038
+ }
1039
+ },
1040
+ onMouseLeave: (e) => {
1041
+ if (!props.disabled) {
1042
+ Object.assign(e.currentTarget.style, getContainerStyles());
1043
+ }
1044
+ },
1045
+ children: [
1046
+ /* @__PURE__ */ jsx(
1047
+ "input",
1048
+ {
1049
+ type: "checkbox",
1050
+ ...props,
1051
+ className: checkboxClassName,
1052
+ style: {
1053
+ ...getCheckboxStyles(),
1054
+ ...getDisabledStyles()
1055
+ },
1056
+ onFocus: (e) => {
1057
+ var _a;
1058
+ if (!props.disabled) {
1059
+ e.currentTarget.style.borderColor = error ? "var(--lm-error-400)" : "var(--lm-primary-400)";
1060
+ }
1061
+ (_a = props.onFocus) == null ? void 0 : _a.call(props, e);
1062
+ },
1063
+ onBlur: (e) => {
1064
+ var _a;
1065
+ if (!props.disabled) {
1066
+ e.currentTarget.style.borderColor = error ? "var(--lm-error-300)" : "var(--lm-border-default)";
1067
+ }
1068
+ (_a = props.onBlur) == null ? void 0 : _a.call(props, e);
1069
+ }
1070
+ }
1071
+ ),
1072
+ /* @__PURE__ */ jsxs("div", { className: "flex-1", children: [
1073
+ /* @__PURE__ */ jsx(
1074
+ "span",
1075
+ {
1076
+ className: `font-medium leading-tight transition-colors duration-200 ${currentSize.label}`,
1077
+ style: getLabelStyles(),
1078
+ children: label
1079
+ }
1080
+ ),
1081
+ description && /* @__PURE__ */ jsx(
1082
+ "p",
1083
+ {
1084
+ className: currentSize.description,
1085
+ style: getDescriptionStyles(),
1086
+ children: description
1087
+ }
1088
+ )
1089
+ ] })
1090
+ ]
1091
+ }
1092
+ ),
1093
+ errorMessage && /* @__PURE__ */ jsxs(
1094
+ "p",
1095
+ {
1096
+ className: `flex items-center gap-1 ${currentSize.errorMessage}`,
1097
+ style: { color: "var(--lm-error-500)" },
1098
+ children: [
1099
+ /* @__PURE__ */ jsx(
1100
+ "svg",
1101
+ {
1102
+ className: "w-3 h-3",
1103
+ fill: "currentColor",
1104
+ viewBox: "0 0 20 20",
1105
+ "aria-hidden": "true",
1106
+ children: /* @__PURE__ */ jsx(
1107
+ "path",
1108
+ {
1109
+ fillRule: "evenodd",
1110
+ 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",
1111
+ clipRule: "evenodd"
1112
+ }
1113
+ )
1114
+ }
1115
+ ),
1116
+ errorMessage
1117
+ ]
1118
+ }
1119
+ )
1120
+ ] });
1121
+ };
1122
+ const LMRadio = ({
1123
+ label,
1124
+ description,
1125
+ error = false,
1126
+ errorMessage,
1127
+ size = "md",
1128
+ className = "",
1129
+ id,
1130
+ ...props
1131
+ }) => {
1132
+ const autoId = useId();
1133
+ const controlId = id ?? `lm-radio-${autoId}`;
1134
+ const errId = `lm-radio-err-${autoId}`;
1135
+ const radioSizeClass = SIZE_ICON_CONFIG[size];
1136
+ const getRadioStyles = () => {
1137
+ const baseStyles = {
1138
+ backgroundColor: "var(--lm-bg-elevated)",
1139
+ borderColor: error ? "var(--lm-error-300)" : "var(--lm-border-default)",
1140
+ color: "var(--lm-primary-500)"
1141
+ };
1142
+ return {
1143
+ ...baseStyles,
1144
+ "--tw-ring-color": error ? "var(--lm-error-400)" : "var(--lm-primary-400)",
1145
+ "--tw-ring-opacity": "0.3"
1146
+ };
1147
+ };
1148
+ const getDisabledStyles = () => {
1149
+ if (props.disabled) {
1150
+ return {
1151
+ backgroundColor: "var(--lm-bg-paper)",
1152
+ borderColor: "var(--lm-border-light)",
1153
+ color: "var(--lm-text-disabled)",
1154
+ cursor: "not-allowed",
1155
+ opacity: 0.6
1156
+ };
1157
+ }
1158
+ return {};
1159
+ };
1160
+ const getContainerStyles = () => {
1161
+ const base = { backgroundColor: "var(--lm-bg-paper)" };
1162
+ return error ? { ...base, backgroundColor: "var(--lm-error-50)" } : base;
1163
+ };
1164
+ const getHoverContainerStyles = () => error ? { backgroundColor: "var(--lm-error-100)" } : { backgroundColor: "var(--lm-bg-elevated)" };
1165
+ const getLabelStyles = () => {
1166
+ if (error) return { color: "var(--lm-error-700)" };
1167
+ if (props.disabled)
1168
+ return { color: "var(--lm-text-disabled)", cursor: "not-allowed" };
1169
+ return { color: "var(--lm-text-primary)", cursor: "pointer" };
1170
+ };
1171
+ const getDescriptionStyles = () => error ? { color: "var(--lm-error-600)" } : { color: "var(--lm-text-secondary)" };
1172
+ const radioClassName = `
1173
+ ${radioSizeClass} border-2 rounded-full
1174
+ focus:ring-2 focus:ring-offset-0
1175
+ transition-all duration-200
1176
+ ${className}
1177
+ `.trim().replace(/\s+/g, " ");
1178
+ return /* @__PURE__ */ jsxs("div", { children: [
1179
+ /* @__PURE__ */ jsxs(
1180
+ "div",
1181
+ {
1182
+ className: "flex items-start gap-3 p-4 rounded-2xl transition-colors duration-200",
1183
+ style: getContainerStyles(),
1184
+ onMouseEnter: (e) => {
1185
+ if (!props.disabled)
1186
+ Object.assign(e.currentTarget.style, getHoverContainerStyles());
1187
+ },
1188
+ onMouseLeave: (e) => {
1189
+ if (!props.disabled)
1190
+ Object.assign(e.currentTarget.style, getContainerStyles());
1191
+ },
1192
+ children: [
1193
+ /* @__PURE__ */ jsx(
1194
+ "input",
1195
+ {
1196
+ type: "radio",
1197
+ id: controlId,
1198
+ ...props,
1199
+ className: radioClassName,
1200
+ "aria-invalid": error || void 0,
1201
+ "aria-describedby": errorMessage ? errId : void 0,
1202
+ style: { ...getRadioStyles(), ...getDisabledStyles() },
1203
+ onFocus: (e) => {
1204
+ var _a;
1205
+ if (!props.disabled) {
1206
+ e.currentTarget.style.borderColor = error ? "var(--lm-error-400)" : "var(--lm-primary-400)";
1207
+ }
1208
+ (_a = props.onFocus) == null ? void 0 : _a.call(props, e);
1209
+ },
1210
+ onBlur: (e) => {
1211
+ var _a;
1212
+ if (!props.disabled) {
1213
+ e.currentTarget.style.borderColor = error ? "var(--lm-error-300)" : "var(--lm-border-default)";
1214
+ }
1215
+ (_a = props.onBlur) == null ? void 0 : _a.call(props, e);
1216
+ }
1217
+ }
1218
+ ),
1219
+ /* @__PURE__ */ jsxs("div", { className: "flex-1", children: [
1220
+ /* @__PURE__ */ jsx(
1221
+ "label",
1222
+ {
1223
+ htmlFor: controlId,
1224
+ className: "text-base font-medium transition-colors duration-200",
1225
+ style: getLabelStyles(),
1226
+ children: label
1227
+ }
1228
+ ),
1229
+ description && /* @__PURE__ */ jsx("p", { className: "text-sm mt-1", style: getDescriptionStyles(), children: description })
1230
+ ] })
1231
+ ]
1232
+ }
1233
+ ),
1234
+ errorMessage && /* @__PURE__ */ jsxs(
1235
+ "p",
1236
+ {
1237
+ id: errId,
1238
+ className: "text-xs flex items-center gap-1",
1239
+ style: { color: "var(--lm-error-500)" },
1240
+ role: "alert",
1241
+ "aria-live": "polite",
1242
+ children: [
1243
+ /* @__PURE__ */ jsx(
1244
+ "svg",
1245
+ {
1246
+ className: "w-3 h-3",
1247
+ fill: "currentColor",
1248
+ viewBox: "0 0 20 20",
1249
+ "aria-hidden": "true",
1250
+ children: /* @__PURE__ */ jsx(
1251
+ "path",
1252
+ {
1253
+ fillRule: "evenodd",
1254
+ 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",
1255
+ clipRule: "evenodd"
1256
+ }
1257
+ )
1258
+ }
1259
+ ),
1260
+ errorMessage
1261
+ ]
1262
+ }
1263
+ )
1264
+ ] });
1265
+ };
1266
+ const sizeConfig$1 = {
1267
+ xs: {
1268
+ container: "p-2 gap-2",
1269
+ label: "text-xs",
1270
+ description: "text-xs mt-0.5",
1271
+ errorMessage: "text-xs",
1272
+ track: "w-7 h-4",
1273
+ thumb: "w-2.5 h-2.5",
1274
+ translate: "translate-x-3"
1275
+ },
1276
+ sm: {
1277
+ container: "p-3 gap-2.5",
1278
+ label: "text-sm",
1279
+ description: "text-xs mt-1",
1280
+ errorMessage: "text-xs",
1281
+ track: "w-9 h-5",
1282
+ thumb: "w-3 h-3",
1283
+ translate: "translate-x-4"
1284
+ },
1285
+ md: {
1286
+ container: "p-4 gap-3",
1287
+ label: "text-base",
1288
+ description: "text-sm mt-1",
1289
+ errorMessage: "text-xs",
1290
+ track: "w-11 h-6",
1291
+ thumb: "w-4 h-4",
1292
+ translate: "translate-x-5"
1293
+ },
1294
+ lg: {
1295
+ container: "p-5 gap-4",
1296
+ label: "text-lg",
1297
+ description: "text-base mt-1.5",
1298
+ errorMessage: "text-sm",
1299
+ track: "w-14 h-7",
1300
+ thumb: "w-5 h-5",
1301
+ translate: "translate-x-7"
1302
+ },
1303
+ xl: {
1304
+ container: "p-6 gap-4",
1305
+ label: "text-xl",
1306
+ description: "text-lg mt-2",
1307
+ errorMessage: "text-sm",
1308
+ track: "w-16 h-8",
1309
+ thumb: "w-6 h-6",
1310
+ translate: "translate-x-8"
1311
+ },
1312
+ "2xl": {
1313
+ container: "p-8 gap-5",
1314
+ label: "text-2xl",
1315
+ description: "text-xl mt-2.5",
1316
+ errorMessage: "text-base",
1317
+ track: "w-20 h-10",
1318
+ thumb: "w-8 h-8",
1319
+ translate: "translate-x-10"
1320
+ }
1321
+ };
1322
+ const LMSwitch = ({
1323
+ label,
1324
+ description,
1325
+ error = false,
1326
+ errorMessage,
1327
+ size = "md",
1328
+ id,
1329
+ ...props
1330
+ }) => {
1331
+ const autoId = useId();
1332
+ const controlId = id ?? `lm-switch-${autoId}`;
1333
+ const errId = `lm-switch-err-${autoId}`;
1334
+ const currentSize = sizeConfig$1[size];
1335
+ const getTrackBg = () => {
1336
+ if (props.disabled) return "var(--lm-bg-paper)";
1337
+ if (error && !props.checked) return "var(--lm-error-300)";
1338
+ if (props.checked) return "var(--lm-primary-500)";
1339
+ return "var(--lm-border-default)";
1340
+ };
1341
+ const getDisabledStyles = () => {
1342
+ if (props.disabled) {
1343
+ return {
1344
+ opacity: 0.6,
1345
+ cursor: "not-allowed"
1346
+ };
1347
+ }
1348
+ return {};
1349
+ };
1350
+ const getContainerStyles = () => {
1351
+ const base = { backgroundColor: "var(--lm-bg-paper)" };
1352
+ return error ? { ...base, backgroundColor: "var(--lm-error-50)" } : base;
1353
+ };
1354
+ const getHoverContainerStyles = () => error ? { backgroundColor: "var(--lm-error-100)" } : { backgroundColor: "var(--lm-bg-elevated)" };
1355
+ const getLabelStyles = () => {
1356
+ if (error) return { color: "var(--lm-error-700)" };
1357
+ if (props.disabled)
1358
+ return { color: "var(--lm-text-disabled)", cursor: "not-allowed" };
1359
+ return { color: "var(--lm-text-primary)", cursor: "pointer" };
1360
+ };
1361
+ const getDescriptionStyles = () => error ? { color: "var(--lm-error-600)" } : { color: "var(--lm-text-secondary)" };
1362
+ return /* @__PURE__ */ jsxs("div", { children: [
1363
+ /* @__PURE__ */ jsxs(
1364
+ "label",
1365
+ {
1366
+ htmlFor: controlId,
1367
+ className: `flex items-start rounded-2xl transition-colors duration-200 ${currentSize.container} ${props.disabled ? "" : "cursor-pointer"}`,
1368
+ style: getContainerStyles(),
1369
+ onMouseEnter: (e) => {
1370
+ if (!props.disabled) {
1371
+ Object.assign(e.currentTarget.style, getHoverContainerStyles());
1372
+ }
1373
+ },
1374
+ onMouseLeave: (e) => {
1375
+ if (!props.disabled) {
1376
+ Object.assign(e.currentTarget.style, getContainerStyles());
1377
+ }
1378
+ },
1379
+ children: [
1380
+ /* @__PURE__ */ jsxs("div", { className: "flex-shrink-0 relative", children: [
1381
+ /* @__PURE__ */ jsx(
1382
+ "input",
1383
+ {
1384
+ type: "checkbox",
1385
+ id: controlId,
1386
+ ...props,
1387
+ className: "sr-only peer",
1388
+ "aria-invalid": error || void 0,
1389
+ "aria-describedby": errorMessage ? errId : void 0,
1390
+ style: getDisabledStyles()
1391
+ }
1392
+ ),
1393
+ /* @__PURE__ */ jsx(
1394
+ "div",
1395
+ {
1396
+ className: `${currentSize.track} rounded-full transition-all duration-300 relative`,
1397
+ style: {
1398
+ backgroundColor: getTrackBg(),
1399
+ ...getDisabledStyles()
1400
+ },
1401
+ children: /* @__PURE__ */ jsx(
1402
+ "div",
1403
+ {
1404
+ className: `${currentSize.thumb} absolute left-1 top-1/2 -translate-y-1/2 rounded-full transition-transform duration-300 ${props.checked ? currentSize.translate : "translate-x-0"}`,
1405
+ style: {
1406
+ backgroundColor: "var(--lm-bg-elevated)",
1407
+ boxShadow: "0 1px 3px rgba(0, 0, 0, 0.1)"
1408
+ }
1409
+ }
1410
+ )
1411
+ }
1412
+ )
1413
+ ] }),
1414
+ (label || description) && /* @__PURE__ */ jsxs("div", { className: "flex-1", children: [
1415
+ label && /* @__PURE__ */ jsx(
1416
+ "span",
1417
+ {
1418
+ className: `font-medium leading-tight transition-colors duration-200 ${currentSize.label}`,
1419
+ style: getLabelStyles(),
1420
+ children: label
1421
+ }
1422
+ ),
1423
+ description && /* @__PURE__ */ jsx(
1424
+ "p",
1425
+ {
1426
+ className: currentSize.description,
1427
+ style: getDescriptionStyles(),
1428
+ children: description
1429
+ }
1430
+ )
1431
+ ] })
1432
+ ]
1433
+ }
1434
+ ),
1435
+ errorMessage && /* @__PURE__ */ jsxs(
1436
+ "p",
1437
+ {
1438
+ id: errId,
1439
+ className: `flex items-center gap-1 mt-2 ${currentSize.errorMessage}`,
1440
+ style: { color: "var(--lm-error-500)" },
1441
+ role: "alert",
1442
+ "aria-live": "polite",
1443
+ children: [
1444
+ /* @__PURE__ */ jsx(
1445
+ "svg",
1446
+ {
1447
+ className: "w-3 h-3",
1448
+ fill: "currentColor",
1449
+ viewBox: "0 0 20 20",
1450
+ "aria-hidden": "true",
1451
+ children: /* @__PURE__ */ jsx(
1452
+ "path",
1453
+ {
1454
+ fillRule: "evenodd",
1455
+ 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",
1456
+ clipRule: "evenodd"
1457
+ }
1458
+ )
1459
+ }
1460
+ ),
1461
+ errorMessage
1462
+ ]
1463
+ }
1464
+ )
1465
+ ] });
1466
+ };
1467
+ const sizeConfig = {
1468
+ xs: {
1469
+ minHeight: "min-h-[60px]",
1470
+ fontSize: "text-xs",
1471
+ padding: "px-3 py-2"
1472
+ },
1473
+ sm: {
1474
+ minHeight: "min-h-[80px]",
1475
+ fontSize: "text-sm",
1476
+ padding: "px-3 py-2"
1477
+ },
1478
+ md: {
1479
+ minHeight: "min-h-[100px]",
1480
+ fontSize: "text-sm",
1481
+ padding: "px-4 py-2.5"
1482
+ },
1483
+ lg: {
1484
+ minHeight: "min-h-[120px]",
1485
+ fontSize: "text-base",
1486
+ padding: "px-4 py-3"
1487
+ },
1488
+ xl: {
1489
+ minHeight: "min-h-[140px]",
1490
+ fontSize: "text-base",
1491
+ padding: "px-5 py-3.5"
1492
+ },
1493
+ "2xl": {
1494
+ minHeight: "min-h-[160px]",
1495
+ fontSize: "text-lg",
1496
+ padding: "px-6 py-4"
1497
+ }
1498
+ };
1499
+ const LMTextarea = ({
1500
+ error = false,
1501
+ errorMessage,
1502
+ className = "",
1503
+ size = "md",
1504
+ ...props
1505
+ }) => {
1506
+ const baseClassName = `
1507
+ w-full ${sizeConfig[size].padding} ${sizeConfig[size].fontSize} backdrop-blur-md border rounded-2xl
1508
+ focus:ring-2 focus:outline-none transition-all duration-300
1509
+ shadow-sm resize-none ${className.includes("h-full") ? "" : sizeConfig[size].minHeight}
1510
+ ${className}
1511
+ `.trim().replace(/\s+/g, " ");
1512
+ const getTextareaStyles = () => {
1513
+ const baseStyles = {
1514
+ backgroundColor: "var(--lm-bg-elevated)",
1515
+ color: "var(--lm-text-primary)",
1516
+ borderColor: error ? "var(--lm-error-300)" : "var(--lm-border-default)",
1517
+ boxShadow: "var(--lm-shadow-sm)"
1518
+ };
1519
+ return {
1520
+ ...baseStyles,
1521
+ "--tw-ring-color": error ? "var(--lm-error-400)" : "var(--lm-primary-400)",
1522
+ "--tw-ring-opacity": "0.3"
1523
+ };
1524
+ };
1525
+ const getDisabledStyles = () => {
1526
+ if (props.disabled) {
1527
+ return {
1528
+ backgroundColor: "var(--lm-bg-paper)",
1529
+ color: "var(--lm-text-disabled)",
1530
+ cursor: "not-allowed",
1531
+ opacity: 0.6
1532
+ };
1533
+ }
1534
+ return {};
1535
+ };
1536
+ const isFullHeight = className.includes("h-full");
1537
+ const containerClassName = isFullHeight ? "h-full flex flex-col" : "space-y-2";
1538
+ return /* @__PURE__ */ jsxs("div", { className: containerClassName, children: [
1539
+ /* @__PURE__ */ jsx(
1540
+ "textarea",
1541
+ {
1542
+ ...props,
1543
+ className: baseClassName,
1544
+ style: {
1545
+ ...getTextareaStyles(),
1546
+ ...getDisabledStyles()
1547
+ },
1548
+ onMouseEnter: (e) => {
1549
+ var _a;
1550
+ if (!props.disabled && !error) {
1551
+ e.currentTarget.style.borderColor = "var(--lm-border-strong)";
1552
+ }
1553
+ (_a = props.onMouseEnter) == null ? void 0 : _a.call(props, e);
1554
+ },
1555
+ onMouseLeave: (e) => {
1556
+ var _a;
1557
+ if (!props.disabled && !error) {
1558
+ e.currentTarget.style.borderColor = "var(--lm-border-default)";
1559
+ }
1560
+ (_a = props.onMouseLeave) == null ? void 0 : _a.call(props, e);
1561
+ },
1562
+ onFocus: (e) => {
1563
+ var _a;
1564
+ if (!props.disabled) {
1565
+ e.currentTarget.style.borderColor = error ? "var(--lm-error-400)" : "var(--lm-primary-400)";
1566
+ }
1567
+ (_a = props.onFocus) == null ? void 0 : _a.call(props, e);
1568
+ },
1569
+ onBlur: (e) => {
1570
+ var _a;
1571
+ if (!props.disabled) {
1572
+ e.currentTarget.style.borderColor = error ? "var(--lm-error-300)" : "var(--lm-border-default)";
1573
+ }
1574
+ (_a = props.onBlur) == null ? void 0 : _a.call(props, e);
1575
+ }
1576
+ }
1577
+ ),
1578
+ errorMessage && /* @__PURE__ */ jsxs(
1579
+ "p",
1580
+ {
1581
+ className: "text-xs flex items-center gap-1",
1582
+ style: { color: "var(--lm-error-500)" },
1583
+ children: [
1584
+ /* @__PURE__ */ jsx("svg", { className: "w-3 h-3", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ jsx(
1585
+ "path",
1586
+ {
1587
+ fillRule: "evenodd",
1588
+ 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",
1589
+ clipRule: "evenodd"
1590
+ }
1591
+ ) }),
1592
+ errorMessage
1593
+ ]
1594
+ }
1595
+ )
1596
+ ] });
1597
+ };
1598
+ const LMNumberInput = ({
1599
+ value,
1600
+ onChange,
1601
+ error = false,
1602
+ errorMessage,
1603
+ placeholder = "Enter number...",
1604
+ disabled = false,
1605
+ className = "",
1606
+ name,
1607
+ size = "md",
1608
+ min,
1609
+ max,
1610
+ step = 1,
1611
+ precision = 0,
1612
+ showControls = true,
1613
+ prefix,
1614
+ suffix
1615
+ }) => {
1616
+ const [inputValue, setInputValue] = useState(
1617
+ value !== null && value !== void 0 ? String(value) : ""
1618
+ );
1619
+ const [isFocused, setIsFocused] = useState(false);
1620
+ const inputRef = useRef(null);
1621
+ const errId = useRef(`lm-ni-err-${Math.random().toString(36).slice(2)}`).current;
1622
+ const formatNumber = useCallback(
1623
+ (num) => {
1624
+ if (!Number.isFinite(num)) return "";
1625
+ if (precision <= 0) return String(Math.round(num));
1626
+ return num.toFixed(precision);
1627
+ },
1628
+ [precision]
1629
+ );
1630
+ useEffect(() => {
1631
+ if (value === void 0 || value === null) {
1632
+ setInputValue("");
1633
+ } else if (!isFocused) {
1634
+ setInputValue(formatNumber(value));
1635
+ }
1636
+ }, [value, isFocused, formatNumber]);
1637
+ const baseClassName = `
1638
+ w-full ${SIZE_INPUT_CONFIG[size].padding} ${SIZE_INPUT_CONFIG[size].height} ${SIZE_INPUT_CONFIG[size].fontSize}
1639
+ backdrop-blur-md border rounded-2xl
1640
+ focus:ring-2 focus:outline-none transition-all duration-300
1641
+ shadow-sm
1642
+ ${showControls ? "pr-10" : ""}
1643
+ ${prefix ? "pl-10" : ""}
1644
+ ${suffix ? "pr-10" : ""}
1645
+ ${className}
1646
+ [&::-webkit-outer-spin-button]:appearance-none
1647
+ [&::-webkit-inner-spin-button]:appearance-none
1648
+ [-moz-appearance:textfield]
1649
+ `.trim().replace(/\s+/g, " ");
1650
+ const getNumberInputStyles = () => {
1651
+ const base = {
1652
+ backgroundColor: "var(--lm-bg-elevated)",
1653
+ color: "var(--lm-text-primary)",
1654
+ borderColor: error ? "var(--lm-error-300)" : isFocused ? "var(--lm-primary-400)" : "var(--lm-border-default)",
1655
+ boxShadow: "var(--lm-shadow-sm)"
1656
+ };
1657
+ return {
1658
+ ...base,
1659
+ "--tw-ring-color": error ? "var(--lm-error-400)" : "var(--lm-primary-400)",
1660
+ "--tw-ring-opacity": "0.3"
1661
+ };
1662
+ };
1663
+ const getDisabledStyles = () => disabled ? {
1664
+ backgroundColor: "var(--lm-bg-paper)",
1665
+ color: "var(--lm-text-disabled)",
1666
+ cursor: "not-allowed",
1667
+ opacity: 0.6
1668
+ } : {};
1669
+ const getIconStyles = () => {
1670
+ if (error) return { color: "var(--lm-error-400)" };
1671
+ if (isFocused) return { color: "var(--lm-primary-500)" };
1672
+ return { color: "var(--lm-text-secondary)" };
1673
+ };
1674
+ const getControlButtonStyles = () => ({
1675
+ backgroundColor: "var(--lm-bg-paper)",
1676
+ color: "var(--lm-text-secondary)",
1677
+ borderColor: "var(--lm-border-light)"
1678
+ });
1679
+ const getHoverControlButtonStyles = () => ({
1680
+ backgroundColor: "var(--lm-bg-elevated)",
1681
+ color: "var(--lm-text-primary)"
1682
+ });
1683
+ const parseNumber = (str) => {
1684
+ const n = parseFloat(str);
1685
+ return Number.isNaN(n) ? null : n;
1686
+ };
1687
+ const clamp = (num) => {
1688
+ let v = num;
1689
+ if (min !== void 0) v = Math.max(v, min);
1690
+ if (max !== void 0) v = Math.min(v, max);
1691
+ return v;
1692
+ };
1693
+ const stepFrom = useMemo(() => min ?? 0, [min]);
1694
+ const alignToStep = (num) => {
1695
+ const offset = num - stepFrom;
1696
+ const k = Math.round(offset / step);
1697
+ const next = stepFrom + k * step;
1698
+ return Number(next.toFixed(Math.max(precision, 12)));
1699
+ };
1700
+ const handleInputChange = (event) => {
1701
+ const val = event.target.value;
1702
+ setInputValue(val);
1703
+ if (val.trim() === "") {
1704
+ onChange == null ? void 0 : onChange(null);
1705
+ return;
1706
+ }
1707
+ const num = parseNumber(val);
1708
+ if (num === null) return;
1709
+ const clamped = clamp(num);
1710
+ if (clamped !== num) return;
1711
+ onChange == null ? void 0 : onChange(num);
1712
+ };
1713
+ const changeByStep = (delta) => {
1714
+ if (disabled) return;
1715
+ const current = parseNumber(inputValue);
1716
+ const base = current ?? min ?? 0;
1717
+ const raw = base + delta * step;
1718
+ const clamped = clamp(raw);
1719
+ const aligned = alignToStep(clamped);
1720
+ setInputValue(formatNumber(aligned));
1721
+ onChange == null ? void 0 : onChange(aligned);
1722
+ };
1723
+ const handleIncrement = () => changeByStep(1);
1724
+ const handleDecrement = () => changeByStep(-1);
1725
+ const handleKeyDown = (event) => {
1726
+ if (event.key === "ArrowUp") {
1727
+ event.preventDefault();
1728
+ handleIncrement();
1729
+ } else if (event.key === "ArrowDown") {
1730
+ event.preventDefault();
1731
+ handleDecrement();
1732
+ }
1733
+ };
1734
+ const handleFocus = () => setIsFocused(true);
1735
+ const handleBlur = () => {
1736
+ setIsFocused(false);
1737
+ if (inputValue.trim() === "") {
1738
+ setInputValue("");
1739
+ if (value !== null) onChange == null ? void 0 : onChange(null);
1740
+ return;
1741
+ }
1742
+ const num = parseNumber(inputValue);
1743
+ if (num === null) {
1744
+ if (typeof value === "number") {
1745
+ setInputValue(formatNumber(clamp(value)));
1746
+ } else {
1747
+ setInputValue("");
1748
+ if (value !== null) onChange == null ? void 0 : onChange(null);
1749
+ }
1750
+ return;
1751
+ }
1752
+ let v = clamp(num);
1753
+ v = alignToStep(v);
1754
+ const formatted = formatNumber(v);
1755
+ setInputValue(formatted);
1756
+ if (v !== value) onChange == null ? void 0 : onChange(v);
1757
+ };
1758
+ const handleWheel = (e) => {
1759
+ if (document.activeElement === inputRef.current) {
1760
+ e.preventDefault();
1761
+ }
1762
+ };
1763
+ const currentNum = parseNumber(inputValue);
1764
+ const incDisabled = useMemo(() => {
1765
+ if (disabled) return true;
1766
+ const base = currentNum ?? min ?? 0;
1767
+ return max !== void 0 && base >= max;
1768
+ }, [disabled, currentNum, min, max]);
1769
+ const decDisabled = useMemo(() => {
1770
+ if (disabled) return true;
1771
+ const base = currentNum ?? min ?? 0;
1772
+ return min !== void 0 && base <= min;
1773
+ }, [disabled, currentNum, min]);
1774
+ const ChevronUp = () => /* @__PURE__ */ jsx("svg", { className: "w-3 h-3", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 15l7-7 7 7" }) });
1775
+ const ChevronDown = () => /* @__PURE__ */ jsx("svg", { className: "w-3 h-3", 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" }) });
1776
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
1777
+ /* @__PURE__ */ jsxs("div", { className: "relative group", children: [
1778
+ prefix && /* @__PURE__ */ jsx("div", { className: "absolute inset-y-0 left-0 pl-4 flex items-center pointer-events-none z-10", children: /* @__PURE__ */ jsx("span", { className: "text-sm font-medium", style: getIconStyles(), children: prefix }) }),
1779
+ /* @__PURE__ */ jsx(
1780
+ "input",
1781
+ {
1782
+ ref: inputRef,
1783
+ type: "number",
1784
+ name,
1785
+ value: inputValue,
1786
+ placeholder,
1787
+ disabled,
1788
+ min,
1789
+ max,
1790
+ step,
1791
+ inputMode: "decimal",
1792
+ className: baseClassName,
1793
+ style: { ...getNumberInputStyles(), ...getDisabledStyles() },
1794
+ "aria-invalid": error || void 0,
1795
+ "aria-describedby": errorMessage ? errId : void 0,
1796
+ onChange: handleInputChange,
1797
+ onKeyDown: handleKeyDown,
1798
+ onFocus: handleFocus,
1799
+ onBlur: handleBlur,
1800
+ onWheel: handleWheel,
1801
+ onMouseEnter: (e) => {
1802
+ if (!disabled && !error && !isFocused) {
1803
+ e.currentTarget.style.borderColor = "var(--lm-border-strong)";
1804
+ }
1805
+ },
1806
+ onMouseLeave: (e) => {
1807
+ if (!disabled && !error && !isFocused) {
1808
+ e.currentTarget.style.borderColor = "var(--lm-border-default)";
1809
+ }
1810
+ }
1811
+ }
1812
+ ),
1813
+ suffix && /* @__PURE__ */ jsx(
1814
+ "div",
1815
+ {
1816
+ className: `absolute inset-y-0 flex items-center pointer-events-none z-10 ${showControls ? "right-10" : "right-4"}`,
1817
+ children: /* @__PURE__ */ jsx("span", { className: "text-sm font-medium", style: getIconStyles(), children: suffix })
1818
+ }
1819
+ ),
1820
+ showControls && /* @__PURE__ */ jsxs("div", { className: "absolute inset-y-0 right-0 flex flex-col w-8", children: [
1821
+ /* @__PURE__ */ jsx(
1822
+ "button",
1823
+ {
1824
+ type: "button",
1825
+ "aria-label": "Increment",
1826
+ onClick: handleIncrement,
1827
+ disabled: incDisabled,
1828
+ className: "flex-1 px-1 border-l border-b rounded-tr-2xl transition-colors duration-200 flex items-center justify-center",
1829
+ style: getControlButtonStyles(),
1830
+ onMouseEnter: (e) => {
1831
+ if (!incDisabled)
1832
+ Object.assign(e.currentTarget.style, getHoverControlButtonStyles());
1833
+ },
1834
+ onMouseLeave: (e) => {
1835
+ if (!incDisabled)
1836
+ Object.assign(e.currentTarget.style, getControlButtonStyles());
1837
+ },
1838
+ children: /* @__PURE__ */ jsx(ChevronUp, {})
1839
+ }
1840
+ ),
1841
+ /* @__PURE__ */ jsx(
1842
+ "button",
1843
+ {
1844
+ type: "button",
1845
+ "aria-label": "Decrement",
1846
+ onClick: handleDecrement,
1847
+ disabled: decDisabled,
1848
+ className: "flex-1 px-1 border-l rounded-br-2xl transition-colors duration-200 flex items-center justify-center",
1849
+ style: getControlButtonStyles(),
1850
+ onMouseEnter: (e) => {
1851
+ if (!decDisabled)
1852
+ Object.assign(e.currentTarget.style, getHoverControlButtonStyles());
1853
+ },
1854
+ onMouseLeave: (e) => {
1855
+ if (!decDisabled)
1856
+ Object.assign(e.currentTarget.style, getControlButtonStyles());
1857
+ },
1858
+ children: /* @__PURE__ */ jsx(ChevronDown, {})
1859
+ }
1860
+ )
1861
+ ] })
1862
+ ] }),
1863
+ errorMessage && /* @__PURE__ */ jsxs(
1864
+ "p",
1865
+ {
1866
+ id: errId,
1867
+ className: "text-xs flex items-center gap-1",
1868
+ style: { color: "var(--lm-error-500)" },
1869
+ role: "alert",
1870
+ "aria-live": "polite",
1871
+ children: [
1872
+ /* @__PURE__ */ jsx("svg", { className: "w-3 h-3", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ jsx(
1873
+ "path",
1874
+ {
1875
+ fillRule: "evenodd",
1876
+ 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",
1877
+ clipRule: "evenodd"
1878
+ }
1879
+ ) }),
1880
+ errorMessage
1881
+ ]
1882
+ }
1883
+ )
1884
+ ] });
1885
+ };
1886
+ const LMSearchInput = ({
1887
+ value,
1888
+ onChange,
1889
+ onSearch,
1890
+ error = false,
1891
+ errorMessage,
1892
+ placeholder = "Search...",
1893
+ disabled = false,
1894
+ className = "",
1895
+ name,
1896
+ size = "md",
1897
+ showClear = true,
1898
+ showSearchButton = true,
1899
+ searchButtonText = "Search",
1900
+ debounceDelay = 300
1901
+ }) => {
1902
+ const [inputValue, setInputValue] = useState(value || "");
1903
+ const [isFocused, setIsFocused] = useState(false);
1904
+ const debounceRef = useRef(null);
1905
+ const inputRef = useRef(null);
1906
+ const searchBtnRef = useRef(null);
1907
+ const [searchBtnWidth, setSearchBtnWidth] = useState(0);
1908
+ useEffect(() => {
1909
+ if (value !== void 0 && value !== null) setInputValue(value);
1910
+ }, [value]);
1911
+ useEffect(() => {
1912
+ if (showSearchButton && searchBtnRef.current) {
1913
+ setSearchBtnWidth(searchBtnRef.current.offsetWidth || 0);
1914
+ } else {
1915
+ setSearchBtnWidth(0);
1916
+ }
1917
+ }, [showSearchButton, searchButtonText]);
1918
+ const baseClassName = `
1919
+ w-full ${SIZE_INPUT_CONFIG[size].padding} ${SIZE_INPUT_CONFIG[size].height} backdrop-blur-md border rounded-2xl
1920
+ focus:ring-2 focus:outline-none transition-all duration-300
1921
+ shadow-sm
1922
+ ${showSearchButton ? "pr-20" : showClear ? "pr-10" : "pr-4"}
1923
+ pl-12
1924
+ ${className}
1925
+ `.trim().replace(/\s+/g, " ");
1926
+ const getSearchInputStyles = () => {
1927
+ const baseStyles = {
1928
+ backgroundColor: "var(--lm-bg-elevated)",
1929
+ color: "var(--lm-text-primary)",
1930
+ borderColor: error ? "var(--lm-error-300)" : isFocused ? "var(--lm-primary-400)" : "var(--lm-border-default)",
1931
+ boxShadow: "var(--lm-shadow-sm)"
1932
+ };
1933
+ return {
1934
+ ...baseStyles,
1935
+ "--tw-ring-color": error ? "var(--lm-error-400)" : "var(--lm-primary-400)",
1936
+ "--tw-ring-opacity": "0.3"
1937
+ };
1938
+ };
1939
+ const getDisabledStyles = () => disabled ? {
1940
+ backgroundColor: "var(--lm-bg-paper)",
1941
+ color: "var(--lm-text-disabled)",
1942
+ cursor: "not-allowed",
1943
+ opacity: 0.6
1944
+ } : {};
1945
+ const getIconStyles = () => {
1946
+ if (error) return { color: "var(--lm-error-400)" };
1947
+ if (isFocused) return { color: "var(--lm-primary-500)" };
1948
+ return { color: "var(--lm-text-secondary)" };
1949
+ };
1950
+ const getButtonStyles = () => ({
1951
+ backgroundColor: "var(--lm-primary-500)",
1952
+ color: "white"
1953
+ });
1954
+ const getClearButtonStyles = () => ({
1955
+ backgroundColor: "var(--lm-bg-paper)",
1956
+ color: "var(--lm-text-secondary)"
1957
+ });
1958
+ const handleInputChange = (event) => {
1959
+ const newValue = event.target.value;
1960
+ setInputValue(newValue);
1961
+ onChange == null ? void 0 : onChange(newValue);
1962
+ if (debounceRef.current) clearTimeout(debounceRef.current);
1963
+ debounceRef.current = setTimeout(() => {
1964
+ onSearch == null ? void 0 : onSearch(newValue);
1965
+ }, debounceDelay);
1966
+ };
1967
+ const handleSearch = () => onSearch == null ? void 0 : onSearch(inputValue);
1968
+ const handleClear = () => {
1969
+ var _a;
1970
+ setInputValue("");
1971
+ onChange == null ? void 0 : onChange("");
1972
+ onSearch == null ? void 0 : onSearch("");
1973
+ (_a = inputRef.current) == null ? void 0 : _a.focus();
1974
+ };
1975
+ const handleKeyDown = (event) => {
1976
+ if (event.key === "Enter") {
1977
+ event.preventDefault();
1978
+ handleSearch();
1979
+ }
1980
+ };
1981
+ const clearBtnSizeClass = size === "sm" ? "w-7 h-7 text-xs" : size === "lg" ? "w-9 h-9 text-sm" : "w-8 h-8 text-sm";
1982
+ const clearRightPx = showSearchButton ? searchBtnWidth + 8 : 8;
1983
+ const SearchIcon = () => /* @__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: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" }) });
1984
+ const ClearIcon = () => /* @__PURE__ */ jsx("svg", { className: "w-3 h-3", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) });
1985
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
1986
+ /* @__PURE__ */ jsxs("div", { className: "relative group", children: [
1987
+ /* @__PURE__ */ jsx("div", { className: "absolute inset-y-0 left-0 pl-4 flex items-center pointer-events-none z-10", children: /* @__PURE__ */ jsx("span", { style: getIconStyles(), children: /* @__PURE__ */ jsx(SearchIcon, {}) }) }),
1988
+ /* @__PURE__ */ jsx(
1989
+ "input",
1990
+ {
1991
+ ref: inputRef,
1992
+ type: "search",
1993
+ name,
1994
+ value: inputValue,
1995
+ placeholder,
1996
+ disabled,
1997
+ className: baseClassName,
1998
+ style: {
1999
+ ...getSearchInputStyles(),
2000
+ ...getDisabledStyles()
2001
+ },
2002
+ onChange: handleInputChange,
2003
+ onKeyDown: handleKeyDown,
2004
+ onFocus: () => setIsFocused(true),
2005
+ onBlur: () => setIsFocused(false),
2006
+ onMouseEnter: (e) => {
2007
+ if (!disabled && !error && !isFocused) {
2008
+ e.currentTarget.style.borderColor = "var(--lm-border-strong)";
2009
+ }
2010
+ },
2011
+ onMouseLeave: (e) => {
2012
+ if (!disabled && !error && !isFocused) {
2013
+ e.currentTarget.style.borderColor = "var(--lm-border-default)";
2014
+ }
2015
+ }
2016
+ }
2017
+ ),
2018
+ /* @__PURE__ */ jsx("style", { children: `
2019
+ input[type='search']::-webkit-search-cancel-button {
2020
+ -webkit-appearance: none;
2021
+ appearance: none;
2022
+ }
2023
+ ` }),
2024
+ showClear && inputValue && !disabled && /* @__PURE__ */ jsx(
2025
+ "button",
2026
+ {
2027
+ onClick: handleClear,
2028
+ className: `absolute top-1/2 -translate-y-1/2 z-10 rounded-full flex items-center justify-center ${clearBtnSizeClass}`,
2029
+ style: {
2030
+ ...getClearButtonStyles(),
2031
+ right: `${clearRightPx}px`
2032
+ },
2033
+ onMouseEnter: (e) => {
2034
+ e.currentTarget.style.backgroundColor = "var(--lm-bg-elevated)";
2035
+ e.currentTarget.style.color = "var(--lm-text-primary)";
2036
+ },
2037
+ onMouseLeave: (e) => {
2038
+ e.currentTarget.style.backgroundColor = "var(--lm-bg-paper)";
2039
+ e.currentTarget.style.color = "var(--lm-text-secondary)";
2040
+ },
2041
+ "aria-label": "Clear",
2042
+ type: "button",
2043
+ children: /* @__PURE__ */ jsx(ClearIcon, {})
2044
+ }
2045
+ ),
2046
+ showSearchButton && !disabled && /* @__PURE__ */ jsx(
2047
+ "button",
2048
+ {
2049
+ ref: searchBtnRef,
2050
+ onClick: handleSearch,
2051
+ className: "absolute inset-y-0 right-0 px-4 rounded-r-2xl transition-colors duration-200 z-20",
2052
+ style: getButtonStyles(),
2053
+ onMouseEnter: (e) => {
2054
+ e.currentTarget.style.backgroundColor = "var(--lm-primary-600)";
2055
+ },
2056
+ onMouseLeave: (e) => {
2057
+ e.currentTarget.style.backgroundColor = "var(--lm-primary-500)";
2058
+ },
2059
+ type: "button",
2060
+ children: /* @__PURE__ */ jsx("span", { className: "text-sm font-medium", children: searchButtonText })
2061
+ }
2062
+ )
2063
+ ] }),
2064
+ errorMessage && /* @__PURE__ */ jsxs(
2065
+ "p",
2066
+ {
2067
+ className: "text-xs flex items-center gap-1",
2068
+ style: { color: "var(--lm-error-500)" },
2069
+ children: [
2070
+ /* @__PURE__ */ jsx("svg", { className: "w-3 h-3", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ jsx(
2071
+ "path",
2072
+ {
2073
+ fillRule: "evenodd",
2074
+ 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",
2075
+ clipRule: "evenodd"
2076
+ }
2077
+ ) }),
2078
+ errorMessage
2079
+ ]
2080
+ }
2081
+ )
2082
+ ] });
2083
+ };
2084
+ const SIZE_DROPDOWN_CONFIG = {
2085
+ xs: { maxHeight: "max-h-32", optionPadding: "px-3 py-1.5", optionTextSize: "text-xs" },
2086
+ sm: { maxHeight: "max-h-40", optionPadding: "px-3 py-2", optionTextSize: "text-xs" },
2087
+ md: { maxHeight: "max-h-48", optionPadding: "px-4 py-2.5", optionTextSize: "text-sm" },
2088
+ lg: { maxHeight: "max-h-56", optionPadding: "px-4 py-3", optionTextSize: "text-sm" },
2089
+ xl: { maxHeight: "max-h-64", optionPadding: "px-5 py-3", optionTextSize: "text-base" },
2090
+ "2xl": { maxHeight: "max-h-72", optionPadding: "px-6 py-4", optionTextSize: "text-lg" }
2091
+ };
2092
+ const LMSelect = ({
2093
+ options,
2094
+ value,
2095
+ onChange,
2096
+ onDropdownVisibleChange,
2097
+ error = false,
2098
+ errorMessage,
2099
+ placeholder = "Select...",
2100
+ disabled = false,
2101
+ className = "",
2102
+ name,
2103
+ size = "md",
2104
+ multiple = false
2105
+ }) => {
2106
+ const [isOpen, setIsOpen] = useState(false);
2107
+ const [selectedOption, setSelectedOption] = useState(null);
2108
+ const [selectedOptions, setSelectedOptions] = useState([]);
2109
+ const dropdownRef = useRef(null);
2110
+ useEffect(() => {
2111
+ if (!multiple) {
2112
+ if (value !== void 0 && value !== null && !Array.isArray(value)) {
2113
+ const option = options.find((opt) => opt.value === value);
2114
+ setSelectedOption(option || null);
2115
+ } else {
2116
+ setSelectedOption(null);
2117
+ }
2118
+ }
2119
+ }, [value, options, multiple]);
2120
+ useEffect(() => {
2121
+ if (multiple && Array.isArray(value)) {
2122
+ const selectedOpts = options.filter((opt) => value.includes(opt.value));
2123
+ setSelectedOptions(selectedOpts);
2124
+ } else if (multiple) {
2125
+ setSelectedOptions([]);
2126
+ }
2127
+ }, [value, options, multiple]);
2128
+ useEffect(() => {
2129
+ const handleClickOutside = (event) => {
2130
+ if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
2131
+ setIsOpen(false);
2132
+ onDropdownVisibleChange == null ? void 0 : onDropdownVisibleChange(false);
2133
+ }
2134
+ };
2135
+ if (isOpen) {
2136
+ document.addEventListener("mousedown", handleClickOutside);
2137
+ return () => document.removeEventListener("mousedown", handleClickOutside);
2138
+ }
2139
+ }, [isOpen, onDropdownVisibleChange]);
2140
+ const handleSelect = (option) => {
2141
+ if (option.disabled) return;
2142
+ if (multiple) {
2143
+ const currentValues = Array.isArray(value) ? value : [];
2144
+ const isSelected = currentValues.includes(option.value);
2145
+ const newValues = isSelected ? currentValues.filter((v) => v !== option.value) : [...currentValues, option.value];
2146
+ onChange == null ? void 0 : onChange(newValues);
2147
+ } else {
2148
+ setSelectedOption(option);
2149
+ onChange == null ? void 0 : onChange(option.value);
2150
+ setIsOpen(false);
2151
+ onDropdownVisibleChange == null ? void 0 : onDropdownVisibleChange(false);
2152
+ }
2153
+ };
2154
+ const toggleDropdown = () => {
2155
+ if (!disabled) {
2156
+ const newIsOpen = !isOpen;
2157
+ setIsOpen(newIsOpen);
2158
+ onDropdownVisibleChange == null ? void 0 : onDropdownVisibleChange(newIsOpen);
2159
+ }
2160
+ };
2161
+ const baseClassName = `
2162
+ w-full ${SIZE_SELECTOR_CONFIG[size].padding} ${SIZE_SELECTOR_CONFIG[size].height} ${SIZE_SELECTOR_CONFIG[size].fontSize}
2163
+ backdrop-blur-md border rounded-2xl
2164
+ transition-all duration-300 shadow-sm cursor-pointer
2165
+ flex items-center justify-between
2166
+ ${className}
2167
+ `.trim().replace(/\s+/g, " ");
2168
+ const getSelectorStyles = () => {
2169
+ const baseStyles = {
2170
+ backgroundColor: "var(--lm-bg-elevated)",
2171
+ color: "var(--lm-text-primary)",
2172
+ borderColor: error ? "var(--lm-error-300)" : "var(--lm-border-default)",
2173
+ boxShadow: "var(--lm-shadow-sm)"
2174
+ };
2175
+ return {
2176
+ ...baseStyles,
2177
+ "--tw-ring-color": error ? "var(--lm-error-400)" : "var(--lm-primary-400)",
2178
+ "--tw-ring-opacity": "0.3"
2179
+ };
2180
+ };
2181
+ const getDisabledStyles = () => disabled ? {
2182
+ backgroundColor: "var(--lm-bg-paper)",
2183
+ color: "var(--lm-text-disabled)",
2184
+ cursor: "not-allowed",
2185
+ opacity: 0.6
2186
+ } : {};
2187
+ const getIconStyles = () => error ? { color: "var(--lm-error-400)" } : { color: "var(--lm-text-secondary)" };
2188
+ const getDropdownStyles = () => ({
2189
+ backgroundColor: "var(--lm-bg-elevated)",
2190
+ borderColor: "var(--lm-border-default)",
2191
+ boxShadow: "var(--lm-shadow-lg)"
2192
+ });
2193
+ const isOptionSelected = (optionValue) => {
2194
+ if (multiple) {
2195
+ return Array.isArray(value) && value.includes(optionValue);
2196
+ }
2197
+ return (selectedOption == null ? void 0 : selectedOption.value) === optionValue;
2198
+ };
2199
+ const getOptionStyles = (option) => {
2200
+ const baseStyles = {
2201
+ color: option.disabled ? "var(--lm-text-disabled)" : "var(--lm-text-primary)",
2202
+ backgroundColor: option.disabled ? "var(--lm-bg-paper)" : "transparent"
2203
+ };
2204
+ if (isOptionSelected(option.value)) {
2205
+ return {
2206
+ ...baseStyles,
2207
+ backgroundColor: "var(--lm-primary-50)",
2208
+ color: "var(--lm-primary-700)"
2209
+ };
2210
+ }
2211
+ return baseStyles;
2212
+ };
2213
+ const getHoverOptionStyles = (option) => {
2214
+ if (option.disabled) return {};
2215
+ if (isOptionSelected(option.value)) {
2216
+ return { backgroundColor: "var(--lm-primary-100)" };
2217
+ }
2218
+ return { backgroundColor: "var(--lm-bg-paper)" };
2219
+ };
2220
+ const getDisplayText = () => {
2221
+ if (multiple) {
2222
+ if (selectedOptions.length === 0) return placeholder;
2223
+ if (selectedOptions.length === 1) return selectedOptions[0].label;
2224
+ return `${selectedOptions.length} selected`;
2225
+ }
2226
+ return selectedOption ? selectedOption.label : placeholder;
2227
+ };
2228
+ const ChevronDown = () => /* @__PURE__ */ jsx(
2229
+ "svg",
2230
+ {
2231
+ className: `w-4 h-4 transition-transform duration-200 ${isOpen ? "rotate-180" : ""}`,
2232
+ fill: "none",
2233
+ stroke: "currentColor",
2234
+ viewBox: "0 0 24 24",
2235
+ style: getIconStyles(),
2236
+ children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 9l-7 7-7-7" })
2237
+ }
2238
+ );
2239
+ 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" }) });
2240
+ return /* @__PURE__ */ jsxs("div", { className: "relative", ref: dropdownRef, children: [
2241
+ /* @__PURE__ */ jsx(
2242
+ "select",
2243
+ {
2244
+ name,
2245
+ value: multiple ? Array.isArray(value) ? value.map(String) : [] : value !== void 0 && value !== null && !Array.isArray(value) ? String(value) : "",
2246
+ onChange: () => {
2247
+ },
2248
+ className: "sr-only",
2249
+ disabled,
2250
+ tabIndex: -1,
2251
+ multiple,
2252
+ children: options.map((option) => /* @__PURE__ */ jsx("option", { value: option.value, disabled: option.disabled, children: option.label }, option.value))
2253
+ }
2254
+ ),
2255
+ /* @__PURE__ */ jsxs(
2256
+ "div",
2257
+ {
2258
+ className: baseClassName,
2259
+ onClick: toggleDropdown,
2260
+ role: "button",
2261
+ tabIndex: disabled ? -1 : 0,
2262
+ style: {
2263
+ ...getSelectorStyles(),
2264
+ ...getDisabledStyles()
2265
+ },
2266
+ onMouseEnter: (e) => {
2267
+ if (!disabled && !error) {
2268
+ e.currentTarget.style.borderColor = "var(--lm-border-strong)";
2269
+ }
2270
+ },
2271
+ onMouseLeave: (e) => {
2272
+ if (!disabled && !error) {
2273
+ e.currentTarget.style.borderColor = "var(--lm-border-default)";
2274
+ }
2275
+ },
2276
+ onFocus: (e) => {
2277
+ if (!disabled) {
2278
+ e.currentTarget.style.borderColor = error ? "var(--lm-error-400)" : "var(--lm-primary-400)";
2279
+ }
2280
+ },
2281
+ onBlur: (e) => {
2282
+ if (!disabled) {
2283
+ e.currentTarget.style.borderColor = error ? "var(--lm-error-300)" : "var(--lm-border-default)";
2284
+ }
2285
+ },
2286
+ onKeyDown: (e) => {
2287
+ if (e.key === "Enter" || e.key === " ") {
2288
+ e.preventDefault();
2289
+ toggleDropdown();
2290
+ }
2291
+ },
2292
+ children: [
2293
+ /* @__PURE__ */ jsx(
2294
+ "span",
2295
+ {
2296
+ style: {
2297
+ color: multiple && selectedOptions.length > 0 || selectedOption ? "var(--lm-text-primary)" : "var(--lm-text-secondary)"
2298
+ },
2299
+ children: getDisplayText()
2300
+ }
2301
+ ),
2302
+ /* @__PURE__ */ jsx(ChevronDown, {})
2303
+ ]
2304
+ }
2305
+ ),
2306
+ isOpen && /* @__PURE__ */ jsx(
2307
+ "div",
2308
+ {
2309
+ className: `absolute left-0 right-0 z-50 backdrop-blur-md border rounded-xl overflow-y-auto ${SIZE_DROPDOWN_CONFIG[size].maxHeight}`,
2310
+ style: {
2311
+ ...getDropdownStyles(),
2312
+ top: "calc(100% + 4px)"
2313
+ },
2314
+ children: options.map((option, index) => /* @__PURE__ */ jsx(
2315
+ "div",
2316
+ {
2317
+ className: `
2318
+ ${SIZE_DROPDOWN_CONFIG[size].optionPadding} ${SIZE_DROPDOWN_CONFIG[size].optionTextSize} font-medium
2319
+ cursor-pointer transition-all duration-150
2320
+ ${option.disabled ? "cursor-not-allowed" : ""}
2321
+ ${index === 0 ? "rounded-t-xl" : ""}
2322
+ ${index === options.length - 1 ? "rounded-b-xl" : ""}
2323
+ ${index > 0 ? "border-t" : ""}
2324
+ `,
2325
+ style: {
2326
+ ...getOptionStyles(option),
2327
+ borderTopColor: index > 0 ? "var(--lm-border-light)" : "transparent"
2328
+ },
2329
+ onMouseEnter: (e) => {
2330
+ if (!option.disabled) {
2331
+ Object.assign(e.currentTarget.style, getHoverOptionStyles(option));
2332
+ }
2333
+ },
2334
+ onMouseLeave: (e) => {
2335
+ if (!option.disabled) {
2336
+ Object.assign(e.currentTarget.style, getOptionStyles(option));
2337
+ }
2338
+ },
2339
+ onClick: () => handleSelect(option),
2340
+ role: "option",
2341
+ "aria-selected": isOptionSelected(option.value),
2342
+ children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
2343
+ multiple && /* @__PURE__ */ jsx(
2344
+ "input",
2345
+ {
2346
+ type: "checkbox",
2347
+ checked: isOptionSelected(option.value),
2348
+ onChange: () => {
2349
+ },
2350
+ className: "mr-2 cursor-pointer",
2351
+ style: { accentColor: "var(--lm-primary-500)" },
2352
+ onClick: (e) => e.stopPropagation()
2353
+ }
2354
+ ),
2355
+ /* @__PURE__ */ jsx("span", { className: "truncate flex-1", children: option.label }),
2356
+ !multiple && isOptionSelected(option.value) && /* @__PURE__ */ jsx("span", { className: "ml-2 flex-shrink-0", style: { color: "var(--lm-primary-600)" }, children: /* @__PURE__ */ jsx(CheckIcon, {}) })
2357
+ ] })
2358
+ },
2359
+ option.value
2360
+ ))
2361
+ }
2362
+ ),
2363
+ errorMessage && /* @__PURE__ */ jsxs(
2364
+ "p",
2365
+ {
2366
+ className: "text-xs flex items-center gap-1 mt-2",
2367
+ style: { color: "var(--lm-error-500)" },
2368
+ children: [
2369
+ /* @__PURE__ */ jsx("svg", { className: "w-3 h-3", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ jsx(
2370
+ "path",
2371
+ {
2372
+ fillRule: "evenodd",
2373
+ 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",
2374
+ clipRule: "evenodd"
2375
+ }
2376
+ ) }),
2377
+ errorMessage
2378
+ ]
2379
+ }
2380
+ )
2381
+ ] });
2382
+ };
2383
+ const LMField = ({
2384
+ label,
2385
+ required = false,
2386
+ errorMessage,
2387
+ help,
2388
+ children,
2389
+ className = ""
2390
+ }) => {
2391
+ let controlId;
2392
+ const firstChild = Array.isArray(children) ? children.find(Boolean) : children;
2393
+ if (React.isValidElement(firstChild) && typeof firstChild.props.id === "string") {
2394
+ controlId = firstChild.props.id;
2395
+ }
2396
+ const containerClass = `space-y-2 ${className}`.trim().replace(/\s+/g, " ");
2397
+ return /* @__PURE__ */ jsxs("div", { className: containerClass, children: [
2398
+ /* @__PURE__ */ jsxs(
2399
+ "label",
2400
+ {
2401
+ htmlFor: controlId,
2402
+ className: "block text-xs font-semibold tracking-wide",
2403
+ style: { color: "var(--lm-text-primary)" },
2404
+ "aria-required": required || void 0,
2405
+ children: [
2406
+ label,
2407
+ required && /* @__PURE__ */ jsx("span", { className: "ml-1", style: { color: "var(--lm-error-500)" }, children: "*" })
2408
+ ]
2409
+ }
2410
+ ),
2411
+ help && /* @__PURE__ */ jsx("p", { className: "text-xs", style: { color: "var(--lm-text-secondary)" }, children: help }),
2412
+ children,
2413
+ errorMessage && /* @__PURE__ */ jsxs(
2414
+ "p",
2415
+ {
2416
+ className: "text-xs flex items-center gap-1",
2417
+ style: { color: "var(--lm-error-500)" },
2418
+ role: "alert",
2419
+ "aria-live": "polite",
2420
+ children: [
2421
+ /* @__PURE__ */ jsx(
2422
+ "svg",
2423
+ {
2424
+ className: "w-3 h-3",
2425
+ fill: "currentColor",
2426
+ viewBox: "0 0 20 20",
2427
+ "aria-hidden": "true",
2428
+ children: /* @__PURE__ */ jsx(
2429
+ "path",
2430
+ {
2431
+ fillRule: "evenodd",
2432
+ 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",
2433
+ clipRule: "evenodd"
2434
+ }
2435
+ )
2436
+ }
2437
+ ),
2438
+ errorMessage
2439
+ ]
2440
+ }
2441
+ )
2442
+ ] });
2443
+ };
2444
+ const CaretUpIcon = ({ active }) => /* @__PURE__ */ jsx(
2445
+ "svg",
2446
+ {
2447
+ className: "w-2.5 h-2.5",
2448
+ viewBox: "0 0 10 6",
2449
+ fill: "none",
2450
+ style: { color: active ? "var(--lm-primary-500)" : "var(--lm-gray-400)" },
2451
+ children: /* @__PURE__ */ jsx("path", { d: "M5 0L10 6H0L5 0Z", fill: "currentColor" })
2452
+ }
2453
+ );
2454
+ const CaretDownIcon = ({ active }) => /* @__PURE__ */ jsx(
2455
+ "svg",
2456
+ {
2457
+ className: "w-2.5 h-2.5",
2458
+ viewBox: "0 0 10 6",
2459
+ fill: "none",
2460
+ style: { color: active ? "var(--lm-primary-500)" : "var(--lm-gray-400)" },
2461
+ children: /* @__PURE__ */ jsx("path", { d: "M5 6L0 0H10L5 6Z", fill: "currentColor" })
2462
+ }
2463
+ );
2464
+ const ChevronLeftIcon = () => /* @__PURE__ */ jsx("svg", { className: "w-4 h-4", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M15 19l-7-7 7-7" }) });
2465
+ const ChevronRightIcon = () => /* @__PURE__ */ jsx("svg", { className: "w-4 h-4", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M9 5l7 7-7 7" }) });
2466
+ const SpinnerIcon = () => /* @__PURE__ */ jsxs("svg", { className: "w-4 h-4 animate-spin", viewBox: "0 0 24 24", fill: "none", children: [
2467
+ /* @__PURE__ */ jsx(
2468
+ "circle",
2469
+ {
2470
+ className: "opacity-25",
2471
+ cx: "12",
2472
+ cy: "12",
2473
+ r: "10",
2474
+ stroke: "currentColor",
2475
+ strokeWidth: "4"
2476
+ }
2477
+ ),
2478
+ /* @__PURE__ */ jsx(
2479
+ "path",
2480
+ {
2481
+ className: "opacity-75",
2482
+ fill: "currentColor",
2483
+ d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
2484
+ }
2485
+ )
2486
+ ] });
2487
+ const LMTable = ({
2488
+ dataSource,
2489
+ columns,
2490
+ rowKey = "id",
2491
+ pagination,
2492
+ loadMore,
2493
+ loading = false,
2494
+ emptyText = "No data",
2495
+ size = "md",
2496
+ bordered = false,
2497
+ striped = false,
2498
+ selectable = false,
2499
+ selectedRowKeys = [],
2500
+ onSelectionChange,
2501
+ onRowClick,
2502
+ onSortChange,
2503
+ className = "",
2504
+ fullHeight = false,
2505
+ variant = "default"
2506
+ }) => {
2507
+ const [currentPage, setCurrentPage] = useState(1);
2508
+ const [pageSize, setPageSize] = useState(10);
2509
+ const [sortField, setSortField] = useState("");
2510
+ const [sortOrder, setSortOrder] = useState("ascend");
2511
+ const containerRef = useRef(null);
2512
+ const getRowKey = useCallback(
2513
+ (record, index) => {
2514
+ if (typeof rowKey === "function") {
2515
+ return rowKey(record, index);
2516
+ }
2517
+ const key = record[rowKey];
2518
+ return (typeof key === "string" ? key : String(key)) || index.toString();
2519
+ },
2520
+ [rowKey]
2521
+ );
2522
+ const getValueByDataIndex = useCallback((record, dataIndex) => {
2523
+ const parts = String(dataIndex).split(".");
2524
+ let current = record;
2525
+ for (const p of parts) {
2526
+ if (current == null || typeof current !== "object" || !(p in current)) {
2527
+ return "";
2528
+ }
2529
+ current = current[p];
2530
+ }
2531
+ return current;
2532
+ }, []);
2533
+ const handleSort = useCallback(
2534
+ (column) => {
2535
+ if (!column.sorter) return;
2536
+ let newSortOrder = "ascend";
2537
+ if (sortField === column.dataIndex) {
2538
+ newSortOrder = sortOrder === "ascend" ? "descend" : "ascend";
2539
+ }
2540
+ setSortField(column.dataIndex);
2541
+ setSortOrder(newSortOrder);
2542
+ onSortChange == null ? void 0 : onSortChange(column.dataIndex, newSortOrder);
2543
+ },
2544
+ [sortField, sortOrder, onSortChange]
2545
+ );
2546
+ const handlePageChange = useCallback(
2547
+ (page) => {
2548
+ var _a;
2549
+ setCurrentPage(page);
2550
+ (_a = pagination == null ? void 0 : pagination.onChange) == null ? void 0 : _a.call(pagination, page, pageSize);
2551
+ },
2552
+ [pagination, pageSize]
2553
+ );
2554
+ const handlePageSizeChange = useCallback(
2555
+ (newPageSize) => {
2556
+ var _a;
2557
+ setPageSize(newPageSize);
2558
+ setCurrentPage(1);
2559
+ (_a = pagination == null ? void 0 : pagination.onChange) == null ? void 0 : _a.call(pagination, 1, newPageSize);
2560
+ },
2561
+ [pagination]
2562
+ );
2563
+ const handleRowSelect = useCallback(
2564
+ (record, checked) => {
2565
+ const key = getRowKey(record, dataSource.indexOf(record));
2566
+ let newSelectedRowKeys;
2567
+ if (checked) {
2568
+ newSelectedRowKeys = [...selectedRowKeys, key];
2569
+ } else {
2570
+ newSelectedRowKeys = selectedRowKeys.filter((k) => k !== key);
2571
+ }
2572
+ const newSelectedRows = dataSource.filter(
2573
+ (item) => newSelectedRowKeys.includes(getRowKey(item, dataSource.indexOf(item)))
2574
+ );
2575
+ onSelectionChange == null ? void 0 : onSelectionChange(newSelectedRowKeys, newSelectedRows);
2576
+ },
2577
+ [selectedRowKeys, dataSource, getRowKey, onSelectionChange]
2578
+ );
2579
+ const handleSelectAll = useCallback(
2580
+ (checked) => {
2581
+ if (checked) {
2582
+ const allKeys = dataSource.map((record, index) => getRowKey(record, index));
2583
+ onSelectionChange == null ? void 0 : onSelectionChange(allKeys, dataSource);
2584
+ } else {
2585
+ onSelectionChange == null ? void 0 : onSelectionChange([], []);
2586
+ }
2587
+ },
2588
+ [dataSource, getRowKey, onSelectionChange]
2589
+ );
2590
+ const handleScroll = useCallback(() => {
2591
+ if (!(loadMore == null ? void 0 : loadMore.enabled) || loadMore.loading || !loadMore.hasMore) return;
2592
+ const container = containerRef.current;
2593
+ if (!container) return;
2594
+ const { scrollTop, scrollHeight, clientHeight } = container;
2595
+ const threshold = loadMore.threshold || 100;
2596
+ if (scrollTop + clientHeight >= scrollHeight - threshold) {
2597
+ loadMore.onLoadMore();
2598
+ }
2599
+ }, [loadMore]);
2600
+ useEffect(() => {
2601
+ const container = containerRef.current;
2602
+ if (!container || !(loadMore == null ? void 0 : loadMore.enabled)) return;
2603
+ container.addEventListener("scroll", handleScroll);
2604
+ return () => container.removeEventListener("scroll", handleScroll);
2605
+ }, [handleScroll, loadMore == null ? void 0 : loadMore.enabled, loadMore == null ? void 0 : loadMore.loading, loadMore == null ? void 0 : loadMore.hasMore]);
2606
+ useEffect(() => {
2607
+ if ((pagination == null ? void 0 : pagination.current) !== void 0) {
2608
+ setCurrentPage(pagination.current);
2609
+ }
2610
+ if ((pagination == null ? void 0 : pagination.pageSize) !== void 0) {
2611
+ setPageSize(pagination.pageSize);
2612
+ }
2613
+ }, [pagination]);
2614
+ const paginationUiClasses = {
2615
+ xs: {
2616
+ container: "px-3 py-2",
2617
+ text: "text-xs",
2618
+ control: "px-2 py-1 text-xs",
2619
+ gap: "gap-1",
2620
+ select: "px-2 py-1 text-xs",
2621
+ input: "px-2 py-1 text-xs w-14"
2622
+ },
2623
+ sm: {
2624
+ container: "px-3 py-2",
2625
+ text: "text-sm",
2626
+ control: "px-2 py-1 text-sm",
2627
+ gap: "gap-2",
2628
+ select: "px-2 py-1 text-sm",
2629
+ input: "px-2 py-1 text-sm w-16"
2630
+ },
2631
+ md: {
2632
+ container: "px-4 py-3",
2633
+ text: "text-sm",
2634
+ control: "px-3 py-1 text-sm",
2635
+ gap: "gap-2",
2636
+ select: "px-2 py-1 text-sm",
2637
+ input: "px-2 py-1 text-sm w-16"
2638
+ },
2639
+ lg: {
2640
+ container: "px-5 py-3.5",
2641
+ text: "text-base",
2642
+ control: "px-3.5 py-1.5 text-base",
2643
+ gap: "gap-3",
2644
+ select: "px-3 py-1.5 text-base",
2645
+ input: "px-3 py-1.5 text-base w-20"
2646
+ },
2647
+ xl: {
2648
+ container: "px-6 py-4",
2649
+ text: "text-lg",
2650
+ control: "px-4 py-2 text-lg",
2651
+ gap: "gap-3",
2652
+ select: "px-4 py-2 text-lg",
2653
+ input: "px-4 py-2 text-lg w-24"
2654
+ },
2655
+ "2xl": {
2656
+ container: "px-8 py-5",
2657
+ text: "text-xl",
2658
+ control: "px-5 py-2.5 text-xl",
2659
+ gap: "gap-4",
2660
+ select: "px-5 py-2.5 text-xl",
2661
+ input: "px-5 py-2.5 text-xl w-28"
2662
+ }
2663
+ };
2664
+ const totalPages = pagination && pagination.total && pageSize ? Math.max(1, Math.ceil(pagination.total / pageSize)) : 1;
2665
+ const getTableStyles = () => ({
2666
+ backgroundColor: variant === "minimal" ? "transparent" : variant === "soft" ? "var(--lm-bg-paper)" : "var(--lm-bg-elevated)",
2667
+ borderColor: variant === "outline" ? "var(--lm-border-strong)" : bordered ? "var(--lm-border-default)" : "transparent"
2668
+ });
2669
+ const getHeaderStyles = () => ({
2670
+ backgroundColor: variant === "minimal" ? "transparent" : "var(--lm-bg-elevated)",
2671
+ color: "var(--lm-text-primary)",
2672
+ borderColor: variant === "outline" ? "var(--lm-border-strong)" : "var(--lm-border-light)"
2673
+ });
2674
+ const getCellStyles = (isHeader = false) => ({
2675
+ backgroundColor: isHeader ? variant === "minimal" ? "transparent" : "var(--lm-bg-paper)" : variant === "minimal" ? "transparent" : variant === "soft" ? "var(--lm-bg-paper)" : "var(--lm-bg-elevated)",
2676
+ color: "var(--lm-text-primary)",
2677
+ borderColor: variant === "outline" ? "var(--lm-border-strong)" : variant === "minimal" ? "transparent" : "var(--lm-border-light)"
2678
+ });
2679
+ const getRowStyles = (index, isSelected = false) => {
2680
+ const baseStyles = {
2681
+ backgroundColor: isSelected ? "var(--lm-primary-50)" : (striped || variant === "zebra") && index % 2 === 1 ? "var(--lm-bg-paper)" : variant === "minimal" ? "transparent" : variant === "soft" ? "var(--lm-bg-paper)" : "var(--lm-bg-elevated)",
2682
+ color: "var(--lm-text-primary)"
2683
+ };
2684
+ if (isSelected) {
2685
+ return {
2686
+ ...baseStyles,
2687
+ borderColor: "var(--lm-primary-200)"
2688
+ };
2689
+ }
2690
+ return baseStyles;
2691
+ };
2692
+ const getPaginationStyles = () => ({
2693
+ backgroundColor: variant === "minimal" ? "transparent" : variant === "soft" ? "var(--lm-bg-paper)" : "var(--lm-bg-elevated)",
2694
+ color: "var(--lm-text-primary)",
2695
+ borderColor: variant === "outline" ? "var(--lm-border-strong)" : "var(--lm-border-default)",
2696
+ boxShadow: variant === "elevated" ? "var(--lm-shadow-md)" : void 0
2697
+ });
2698
+ const getButtonStyles = (disabled = false, active = false) => {
2699
+ if (disabled) {
2700
+ return {
2701
+ backgroundColor: "var(--lm-bg-paper)",
2702
+ color: "var(--lm-text-disabled)",
2703
+ borderColor: "var(--lm-border-light)",
2704
+ cursor: "not-allowed",
2705
+ opacity: 0.6
2706
+ };
2707
+ }
2708
+ if (active) {
2709
+ return {
2710
+ backgroundColor: "var(--lm-primary-500)",
2711
+ color: "white",
2712
+ borderColor: "var(--lm-primary-500)"
2713
+ };
2714
+ }
2715
+ return {
2716
+ backgroundColor: "var(--lm-bg-paper)",
2717
+ color: "var(--lm-text-primary)",
2718
+ borderColor: "var(--lm-border-default)"
2719
+ };
2720
+ };
2721
+ const getLoadingStyles = () => ({
2722
+ color: "var(--lm-text-secondary)"
2723
+ });
2724
+ const getEmptyStyles = () => ({
2725
+ color: "var(--lm-text-secondary)"
2726
+ });
2727
+ const tableClassName = `w-full ${SIZE_TEXT_CLASSES[size]} border-collapse ${className}`.trim().replace(/\s+/g, " ");
2728
+ const isAllSelected = dataSource.length > 0 && selectedRowKeys.length === dataSource.length;
2729
+ const isIndeterminate = selectedRowKeys.length > 0 && selectedRowKeys.length < dataSource.length;
2730
+ const rootClassName = `space-y-4 ${fullHeight ? "h-full flex flex-col min-h-0" : ""}`.trim().replace(/\s+/g, " ");
2731
+ const tableContainerClassName = `${fullHeight ? "flex-1 min-h-0 overflow-auto" : `overflow-auto ${(loadMore == null ? void 0 : loadMore.enabled) ? "max-h-96" : ""}`}`.trim().replace(/\s+/g, " ");
2732
+ const wrapperVariantClasses = (() => {
2733
+ switch (variant) {
2734
+ case "elevated":
2735
+ return "rounded-2xl border shadow-lg";
2736
+ case "outline":
2737
+ return "rounded-xl border";
2738
+ case "soft":
2739
+ return "rounded-xl border";
2740
+ case "minimal":
2741
+ return "rounded-xl";
2742
+ case "zebra":
2743
+ return "rounded-xl border";
2744
+ default:
2745
+ return "";
2746
+ }
2747
+ })();
2748
+ return /* @__PURE__ */ jsxs("div", { className: rootClassName, children: [
2749
+ /* @__PURE__ */ jsx(
2750
+ "div",
2751
+ {
2752
+ ref: containerRef,
2753
+ className: `${tableContainerClassName} ${wrapperVariantClasses}`,
2754
+ style: { borderColor: "var(--lm-border-default)" },
2755
+ children: /* @__PURE__ */ jsxs("table", { className: tableClassName, style: getTableStyles(), children: [
2756
+ /* @__PURE__ */ jsx("thead", { className: "sticky top-0 z-20", style: getHeaderStyles(), children: /* @__PURE__ */ jsxs("tr", { children: [
2757
+ selectable && /* @__PURE__ */ jsx(
2758
+ "th",
2759
+ {
2760
+ className: `${SIZE_TABLE_CONFIG[size].cellPadding} py-3 ${SIZE_TEXT_CLASSES[size]} text-left ${bordered ? "border-r" : ""} font-semibold`,
2761
+ style: getCellStyles(true),
2762
+ children: /* @__PURE__ */ jsx(
2763
+ "input",
2764
+ {
2765
+ type: "checkbox",
2766
+ checked: isAllSelected,
2767
+ ref: (input) => {
2768
+ if (input) input.indeterminate = isIndeterminate;
2769
+ },
2770
+ onChange: (e) => handleSelectAll(e.target.checked),
2771
+ className: "w-4 h-4",
2772
+ style: { accentColor: "var(--lm-primary-500)" }
2773
+ }
2774
+ )
2775
+ }
2776
+ ),
2777
+ columns.map((column) => /* @__PURE__ */ jsx(
2778
+ "th",
2779
+ {
2780
+ className: `${SIZE_TABLE_CONFIG[size].cellPadding} py-3 text-left ${bordered ? "border-r" : ""} ${column.sorter ? "cursor-pointer hover:bg-opacity-60" : ""} font-semibold`,
2781
+ style: {
2782
+ ...getCellStyles(true),
2783
+ width: column.width,
2784
+ textAlign: column.align || "left",
2785
+ fontSize: size === "xs" ? "0.8125rem" : size === "sm" ? "0.875rem" : "0.9375rem"
2786
+ },
2787
+ onClick: () => handleSort(column),
2788
+ children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
2789
+ /* @__PURE__ */ jsx("span", { children: column.title }),
2790
+ column.sorter && /* @__PURE__ */ jsxs("div", { className: "flex flex-col -space-y-1", children: [
2791
+ /* @__PURE__ */ jsx(
2792
+ CaretUpIcon,
2793
+ {
2794
+ active: sortField === column.dataIndex && sortOrder === "ascend"
2795
+ }
2796
+ ),
2797
+ /* @__PURE__ */ jsx(
2798
+ CaretDownIcon,
2799
+ {
2800
+ active: sortField === column.dataIndex && sortOrder === "descend"
2801
+ }
2802
+ )
2803
+ ] })
2804
+ ] })
2805
+ },
2806
+ column.dataIndex
2807
+ ))
2808
+ ] }) }),
2809
+ /* @__PURE__ */ jsx("tbody", { children: loading ? /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx(
2810
+ "td",
2811
+ {
2812
+ colSpan: columns.length + (selectable ? 1 : 0),
2813
+ className: `px-4 py-8 text-center ${SIZE_TEXT_CLASSES[size]}`,
2814
+ style: getLoadingStyles(),
2815
+ children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-center gap-2", children: [
2816
+ /* @__PURE__ */ jsx(SpinnerIcon, {}),
2817
+ "Loading..."
2818
+ ] })
2819
+ }
2820
+ ) }) : dataSource.length === 0 ? /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx(
2821
+ "td",
2822
+ {
2823
+ colSpan: columns.length + (selectable ? 1 : 0),
2824
+ className: `px-4 py-8 text-center ${SIZE_TEXT_CLASSES[size]}`,
2825
+ style: getEmptyStyles(),
2826
+ children: emptyText
2827
+ }
2828
+ ) }) : dataSource.map((record, index) => {
2829
+ const key = getRowKey(record, index);
2830
+ const isSelected = selectedRowKeys.includes(key);
2831
+ const isLastRow = index === dataSource.length - 1;
2832
+ return /* @__PURE__ */ jsxs(
2833
+ "tr",
2834
+ {
2835
+ className: `${onRowClick ? "cursor-pointer hover:bg-opacity-60" : ""} transition-colors border-t ${isLastRow ? "border-b" : ""}`,
2836
+ style: {
2837
+ ...getRowStyles(index, isSelected),
2838
+ borderColor: "var(--lm-border-light)"
2839
+ },
2840
+ onClick: () => onRowClick == null ? void 0 : onRowClick(record, index),
2841
+ children: [
2842
+ selectable && /* @__PURE__ */ jsx(
2843
+ "td",
2844
+ {
2845
+ className: `${SIZE_TABLE_CONFIG[size].cellPadding} ${SIZE_TEXT_CLASSES[size]} ${bordered ? "border-r" : ""}`,
2846
+ style: getCellStyles(),
2847
+ onClick: (e) => e.stopPropagation(),
2848
+ children: /* @__PURE__ */ jsx(
2849
+ "input",
2850
+ {
2851
+ type: "checkbox",
2852
+ checked: isSelected,
2853
+ onChange: (e) => handleRowSelect(record, e.target.checked),
2854
+ className: "w-4 h-4",
2855
+ style: { accentColor: "var(--lm-primary-500)" }
2856
+ }
2857
+ )
2858
+ }
2859
+ ),
2860
+ columns.map((column) => /* @__PURE__ */ jsx(
2861
+ "td",
2862
+ {
2863
+ className: `${SIZE_TABLE_CONFIG[size].cellPadding} ${SIZE_TEXT_CLASSES[size]} ${bordered ? "border-r" : ""}`,
2864
+ style: {
2865
+ ...getCellStyles(),
2866
+ textAlign: column.align || "left"
2867
+ },
2868
+ children: column.render ? column.render(
2869
+ getValueByDataIndex(record, column.dataIndex),
2870
+ record,
2871
+ index
2872
+ ) : String(getValueByDataIndex(record, column.dataIndex) ?? "")
2873
+ },
2874
+ column.dataIndex
2875
+ ))
2876
+ ]
2877
+ },
2878
+ key
2879
+ );
2880
+ }) })
2881
+ ] })
2882
+ }
2883
+ ),
2884
+ (pagination == null ? void 0 : pagination.showPagination) && /* @__PURE__ */ jsx(
2885
+ "div",
2886
+ {
2887
+ className: `flex items-center justify-between ${paginationUiClasses[size].container} rounded-2xl border`,
2888
+ style: getPaginationStyles(),
2889
+ children: (() => {
2890
+ var _a;
2891
+ const maxButtons = 5;
2892
+ const half = Math.floor(maxButtons / 2);
2893
+ let start = Math.max(1, currentPage - half);
2894
+ const end = Math.min(totalPages, start + maxButtons - 1);
2895
+ if (end - start + 1 < maxButtons) {
2896
+ start = Math.max(1, end - maxButtons + 1);
2897
+ }
2898
+ const pageNumbers = Array.from({ length: end - start + 1 }, (_, i) => start + i);
2899
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
2900
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-4", children: [
2901
+ pagination.showTotal && /* @__PURE__ */ jsxs(
2902
+ "span",
2903
+ {
2904
+ className: paginationUiClasses[size].text,
2905
+ style: { color: "var(--lm-text-secondary)" },
2906
+ children: [
2907
+ "Total ",
2908
+ pagination.total,
2909
+ " items / ",
2910
+ totalPages,
2911
+ " pages"
2912
+ ]
2913
+ }
2914
+ ),
2915
+ pagination.showSizeChanger && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
2916
+ /* @__PURE__ */ jsx(
2917
+ "span",
2918
+ {
2919
+ className: paginationUiClasses[size].text,
2920
+ style: { color: "var(--lm-text-secondary)" },
2921
+ children: "Show:"
2922
+ }
2923
+ ),
2924
+ /* @__PURE__ */ jsx(
2925
+ "select",
2926
+ {
2927
+ value: pageSize,
2928
+ onChange: (e) => handlePageSizeChange(Number(e.target.value)),
2929
+ className: `${paginationUiClasses[size].select} border rounded-lg focus:ring-2 focus:ring-primary-400 focus:outline-none`,
2930
+ style: {
2931
+ backgroundColor: "var(--lm-bg-paper)",
2932
+ color: "var(--lm-text-primary)",
2933
+ borderColor: "var(--lm-border-default)"
2934
+ },
2935
+ children: (_a = pagination.pageSizeOptions) == null ? void 0 : _a.map((s) => /* @__PURE__ */ jsxs("option", { value: s, children: [
2936
+ s,
2937
+ " / page"
2938
+ ] }, s))
2939
+ }
2940
+ )
2941
+ ] })
2942
+ ] }),
2943
+ /* @__PURE__ */ jsxs("div", { className: `flex items-center ${paginationUiClasses[size].gap}`, children: [
2944
+ /* @__PURE__ */ jsx(
2945
+ "button",
2946
+ {
2947
+ onClick: () => handlePageChange(currentPage - 1),
2948
+ disabled: currentPage <= 1,
2949
+ className: `${paginationUiClasses[size].control} border rounded-lg transition-colors`,
2950
+ style: getButtonStyles(currentPage <= 1),
2951
+ "aria-label": "Previous page",
2952
+ title: "Previous page",
2953
+ children: /* @__PURE__ */ jsx(ChevronLeftIcon, {})
2954
+ }
2955
+ ),
2956
+ pageNumbers.map((page) => /* @__PURE__ */ jsx(
2957
+ "button",
2958
+ {
2959
+ onClick: () => handlePageChange(page),
2960
+ className: `${paginationUiClasses[size].control} border rounded-lg transition-colors ${currentPage === page ? "font-medium" : ""}`,
2961
+ style: getButtonStyles(false, currentPage === page),
2962
+ children: page
2963
+ },
2964
+ page
2965
+ )),
2966
+ /* @__PURE__ */ jsx(
2967
+ "button",
2968
+ {
2969
+ onClick: () => handlePageChange(currentPage + 1),
2970
+ disabled: currentPage >= totalPages,
2971
+ className: `${paginationUiClasses[size].control} border rounded-lg transition-colors`,
2972
+ style: getButtonStyles(currentPage >= totalPages),
2973
+ "aria-label": "Next page",
2974
+ title: "Next page",
2975
+ children: /* @__PURE__ */ jsx(ChevronRightIcon, {})
2976
+ }
2977
+ ),
2978
+ pagination.showQuickJumper && /* @__PURE__ */ jsxs("div", { className: `flex items-center ${paginationUiClasses[size].gap} ml-4`, children: [
2979
+ /* @__PURE__ */ jsx(
2980
+ "span",
2981
+ {
2982
+ className: paginationUiClasses[size].text,
2983
+ style: { color: "var(--lm-text-secondary)" },
2984
+ children: "Go to:"
2985
+ }
2986
+ ),
2987
+ /* @__PURE__ */ jsx(
2988
+ "input",
2989
+ {
2990
+ type: "number",
2991
+ min: 1,
2992
+ max: totalPages,
2993
+ className: `${paginationUiClasses[size].input} border rounded-lg focus:ring-2 focus:ring-primary-400 focus:outline-none`,
2994
+ style: {
2995
+ backgroundColor: "var(--lm-bg-paper)",
2996
+ color: "var(--lm-text-primary)",
2997
+ borderColor: "var(--lm-border-default)"
2998
+ },
2999
+ onKeyDown: (e) => {
3000
+ if (e.key === "Enter") {
3001
+ const page = Number(e.currentTarget.value);
3002
+ if (page >= 1 && page <= totalPages) {
3003
+ handlePageChange(page);
3004
+ }
3005
+ }
3006
+ }
3007
+ }
3008
+ )
3009
+ ] })
3010
+ ] })
3011
+ ] });
3012
+ })()
3013
+ }
3014
+ ),
3015
+ (loadMore == null ? void 0 : loadMore.enabled) && loadMore.hasMore && /* @__PURE__ */ jsx("div", { className: "text-center py-4", children: /* @__PURE__ */ jsx(
3016
+ "button",
3017
+ {
3018
+ onClick: loadMore.onLoadMore,
3019
+ disabled: loadMore.loading,
3020
+ className: "px-6 py-2 text-sm border rounded-2xl transition-colors",
3021
+ style: getButtonStyles(loadMore.loading),
3022
+ children: loadMore.loading ? /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
3023
+ /* @__PURE__ */ jsx(SpinnerIcon, {}),
3024
+ "Loading..."
3025
+ ] }) : "Load more"
3026
+ }
3027
+ ) })
3028
+ ] });
3029
+ };
3030
+ const LMTable_default = memo(LMTable);
3031
+ const ICONS = {
3032
+ success: /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 24 24", className: "h-5 w-5", "aria-hidden": "true", children: [
3033
+ /* @__PURE__ */ jsx(
3034
+ "path",
3035
+ {
3036
+ d: "M12 22a10 10 0 1 1 0-20 10 10 0 0 1 0 20Z",
3037
+ fill: "currentColor",
3038
+ opacity: "0.15"
3039
+ }
3040
+ ),
3041
+ /* @__PURE__ */ jsx(
3042
+ "path",
3043
+ {
3044
+ d: "M16.7 9.3a1 1 0 0 0-1.4-1.4L11 12.2 8.7 9.9a1 1 0 1 0-1.4 1.4l3 3a1 1 0 0 0 1.4 0l5-5Z",
3045
+ fill: "currentColor"
3046
+ }
3047
+ )
3048
+ ] }),
3049
+ error: /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 24 24", className: "h-5 w-5", "aria-hidden": "true", children: [
3050
+ /* @__PURE__ */ jsx(
3051
+ "path",
3052
+ {
3053
+ d: "M12 22c5.5 0 10-4.5 10-10S17.5 2 12 2 2 6.5 2 12s4.5 10 10 10Z",
3054
+ fill: "currentColor",
3055
+ opacity: "0.15"
3056
+ }
3057
+ ),
3058
+ /* @__PURE__ */ jsx(
3059
+ "path",
3060
+ {
3061
+ d: "M15.5 8.5l-7 7M8.5 8.5l7 7",
3062
+ stroke: "currentColor",
3063
+ strokeWidth: "1.8",
3064
+ strokeLinecap: "round"
3065
+ }
3066
+ )
3067
+ ] }),
3068
+ warning: /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 24 24", className: "h-5 w-5", "aria-hidden": "true", children: [
3069
+ /* @__PURE__ */ jsx(
3070
+ "path",
3071
+ {
3072
+ d: "M12.9 4.5c-.4-.7-1.4-.7-1.8 0L3.5 18a1 1 0 0 0 .9 1.5h15.2a1 1 0 0 0 .9-1.5l-7.6-13.5Z",
3073
+ fill: "currentColor",
3074
+ opacity: "0.15"
3075
+ }
3076
+ ),
3077
+ /* @__PURE__ */ jsx("path", { d: "M12 9v5", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round" }),
3078
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "16.5", r: "1", fill: "currentColor" })
3079
+ ] }),
3080
+ info: /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 24 24", className: "h-5 w-5", "aria-hidden": "true", children: [
3081
+ /* @__PURE__ */ jsx(
3082
+ "path",
3083
+ {
3084
+ d: "M12 22a10 10 0 1 0 0-20 10 10 0 0 0 0 20Z",
3085
+ fill: "currentColor",
3086
+ opacity: "0.15"
3087
+ }
3088
+ ),
3089
+ /* @__PURE__ */ jsx(
3090
+ "path",
3091
+ {
3092
+ d: "M12 10.5v5M12 7.5h.01",
3093
+ stroke: "currentColor",
3094
+ strokeWidth: "1.8",
3095
+ strokeLinecap: "round"
3096
+ }
3097
+ )
3098
+ ] })
3099
+ };
3100
+ const useTone = (type) => {
3101
+ switch (type) {
3102
+ case "success":
3103
+ return {
3104
+ accent: "var(--lm-success-500)",
3105
+ background: "color-mix(in srgb, var(--lm-success-100) 60%, transparent)",
3106
+ text: "var(--lm-success-700)",
3107
+ title: "var(--lm-success-800)"
3108
+ };
3109
+ case "error":
3110
+ return {
3111
+ accent: "var(--lm-error-500)",
3112
+ background: "color-mix(in srgb, var(--lm-error-100) 60%, transparent)",
3113
+ text: "var(--lm-error-700)",
3114
+ title: "var(--lm-error-800)"
3115
+ };
3116
+ case "warning":
3117
+ return {
3118
+ accent: "var(--lm-warning-500)",
3119
+ background: "color-mix(in srgb, var(--lm-warning-100) 60%, transparent)",
3120
+ text: "var(--lm-warning-700)",
3121
+ title: "var(--lm-warning-800)"
3122
+ };
3123
+ case "info":
3124
+ default:
3125
+ return {
3126
+ accent: "var(--lm-primary-500)",
3127
+ background: "color-mix(in srgb, var(--lm-primary-100) 60%, transparent)",
3128
+ text: "var(--lm-primary-700)",
3129
+ title: "var(--lm-primary-800)"
3130
+ };
3131
+ }
3132
+ };
3133
+ const LMMessage = ({ id, type, title, content, duration = 2e3, onClose }) => {
3134
+ const tone = useTone(type);
3135
+ useEffect(() => {
3136
+ if (duration <= 0) return;
3137
+ const timer = setTimeout(() => onClose(id), duration);
3138
+ return () => clearTimeout(timer);
3139
+ }, [id, duration, onClose]);
3140
+ const icon = useMemo(() => ICONS[type], [type]);
3141
+ const ariaRole = "status";
3142
+ const ariaLabel = useMemo(() => {
3143
+ switch (type) {
3144
+ case "success":
3145
+ return "Success message";
3146
+ case "error":
3147
+ return "Error message";
3148
+ case "warning":
3149
+ return "Warning message";
3150
+ default:
3151
+ return "Information message";
3152
+ }
3153
+ }, [type]);
3154
+ return /* @__PURE__ */ jsx("div", { className: "max-w-sm mx-auto will-change-transform", role: ariaRole, "aria-label": ariaLabel, children: /* @__PURE__ */ jsx(
3155
+ "div",
3156
+ {
3157
+ className: "rounded-3xl shadow-lg p-5 mb-3 backdrop-blur-md border transition-all duration-300 ease-out",
3158
+ style: {
3159
+ backgroundColor: tone.background,
3160
+ borderColor: "var(--lm-border-light)",
3161
+ boxShadow: "var(--lm-shadow-lg)"
3162
+ },
3163
+ children: /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-4", children: [
3164
+ /* @__PURE__ */ jsx(
3165
+ "div",
3166
+ {
3167
+ className: "mt-0.5 flex h-10 w-10 items-center justify-center rounded-2xl",
3168
+ style: {
3169
+ color: tone.accent,
3170
+ backgroundColor: "color-mix(in srgb, currentColor 12%, transparent)"
3171
+ },
3172
+ children: icon
3173
+ }
3174
+ ),
3175
+ /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
3176
+ title && /* @__PURE__ */ jsx("h4", { className: "text-sm font-semibold mb-2 truncate", style: { color: tone.title }, children: title }),
3177
+ /* @__PURE__ */ jsx("p", { className: "text-sm leading-relaxed break-words", style: { color: tone.text }, children: content })
3178
+ ] }),
3179
+ /* @__PURE__ */ jsx(
3180
+ "button",
3181
+ {
3182
+ onClick: () => onClose(id),
3183
+ "aria-label": "Close message",
3184
+ className: "flex-shrink-0 p-2 rounded-xl transition-all duration-200 hover:bg-black/5 active:bg-black/10",
3185
+ style: { color: tone.accent },
3186
+ children: /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", className: "h-4 w-4", "aria-hidden": "true", children: /* @__PURE__ */ jsx(
3187
+ "path",
3188
+ {
3189
+ d: "M6 6l12 12M18 6L6 18",
3190
+ stroke: "currentColor",
3191
+ strokeWidth: "2",
3192
+ strokeLinecap: "round"
3193
+ }
3194
+ ) })
3195
+ }
3196
+ )
3197
+ ] })
3198
+ }
3199
+ ) });
3200
+ };
3201
+ const LMMessageContainer = ({
3202
+ messages,
3203
+ onClose,
3204
+ position = "top-right"
3205
+ }) => {
3206
+ if (messages.length === 0) return null;
3207
+ const positionClasses = {
3208
+ "top-right": "top-20 right-6",
3209
+ "top-left": "top-20 left-6",
3210
+ "top-center": "top-20 left-1/2 -translate-x-1/2",
3211
+ "bottom-right": "bottom-6 right-6",
3212
+ "bottom-left": "bottom-6 left-6",
3213
+ "bottom-center": "bottom-6 left-1/2 -translate-x-1/2"
3214
+ };
3215
+ return /* @__PURE__ */ jsx("div", { className: `fixed z-50 space-y-3 ${positionClasses[position]}`, children: messages.map((message) => /* @__PURE__ */ jsx(LMMessage, { ...message, onClose }, message.id)) });
3216
+ };
3217
+ let messageIdCounter = 0;
3218
+ const useMessage = () => {
3219
+ const [messages, setMessages] = useState([]);
3220
+ const addMessage = useCallback((message) => {
3221
+ const id = `lm-message-${++messageIdCounter}`;
3222
+ setMessages((prev) => [...prev, { ...message, id }]);
3223
+ return id;
3224
+ }, []);
3225
+ const removeMessage = useCallback((id) => {
3226
+ setMessages((prev) => prev.filter((m) => m.id !== id));
3227
+ }, []);
3228
+ const success = useCallback(
3229
+ (content, title, duration) => {
3230
+ return addMessage({ type: "success", content, title, duration });
3231
+ },
3232
+ [addMessage]
3233
+ );
3234
+ const error = useCallback(
3235
+ (content, title, duration) => {
3236
+ return addMessage({ type: "error", content, title, duration });
3237
+ },
3238
+ [addMessage]
3239
+ );
3240
+ const warning = useCallback(
3241
+ (content, title, duration) => {
3242
+ return addMessage({ type: "warning", content, title, duration });
3243
+ },
3244
+ [addMessage]
3245
+ );
3246
+ const info = useCallback(
3247
+ (content, title, duration) => {
3248
+ return addMessage({ type: "info", content, title, duration });
3249
+ },
3250
+ [addMessage]
3251
+ );
3252
+ const clearAll = useCallback(() => {
3253
+ setMessages([]);
3254
+ }, []);
3255
+ return {
3256
+ messages,
3257
+ addMessage,
3258
+ removeMessage,
3259
+ success,
3260
+ error,
3261
+ warning,
3262
+ info,
3263
+ clearAll
3264
+ };
3265
+ };
3266
+ const QuestionIcon = () => /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 24 24", className: "w-6 h-6", fill: "none", stroke: "currentColor", strokeWidth: 2, children: [
3267
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "10" }),
3268
+ /* @__PURE__ */ jsx("path", { d: "M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3", strokeLinecap: "round", strokeLinejoin: "round" }),
3269
+ /* @__PURE__ */ jsx("path", { d: "M12 17h.01", strokeLinecap: "round", strokeLinejoin: "round" })
3270
+ ] });
3271
+ const LMConfirm = ({
3272
+ visible,
3273
+ title = "Confirm",
3274
+ content,
3275
+ confirmText = "Confirm",
3276
+ cancelText = "Cancel",
3277
+ confirmButtonStyle = "primary",
3278
+ onConfirm,
3279
+ onCancel,
3280
+ closeOnOverlayClick = true
3281
+ }) => {
3282
+ const [isVisible, setIsVisible] = useState(false);
3283
+ const [isAnimating, setIsAnimating] = useState(false);
3284
+ useEffect(() => {
3285
+ if (visible) {
3286
+ setIsVisible(true);
3287
+ requestAnimationFrame(() => {
3288
+ setIsAnimating(true);
3289
+ });
3290
+ } else {
3291
+ setIsAnimating(false);
3292
+ const timer = setTimeout(() => {
3293
+ setIsVisible(false);
3294
+ }, 200);
3295
+ return () => clearTimeout(timer);
3296
+ }
3297
+ }, [visible]);
3298
+ const getConfirmButtonStyles = () => {
3299
+ switch (confirmButtonStyle) {
3300
+ case "primary":
3301
+ return {
3302
+ backgroundColor: "var(--lm-primary-500)",
3303
+ color: "var(--lm-text-inverse)"
3304
+ };
3305
+ case "danger":
3306
+ return {
3307
+ backgroundColor: "var(--lm-error-500)",
3308
+ color: "var(--lm-text-inverse)"
3309
+ };
3310
+ }
3311
+ };
3312
+ const getConfirmButtonHoverStyles = () => {
3313
+ switch (confirmButtonStyle) {
3314
+ case "primary":
3315
+ return {
3316
+ backgroundColor: "var(--lm-primary-600)"
3317
+ };
3318
+ case "danger":
3319
+ return {
3320
+ backgroundColor: "var(--lm-error-600)"
3321
+ };
3322
+ }
3323
+ };
3324
+ const handleOverlayClick = () => {
3325
+ if (closeOnOverlayClick) {
3326
+ onCancel();
3327
+ }
3328
+ };
3329
+ if (!isVisible) return null;
3330
+ return /* @__PURE__ */ jsxs("div", { className: "fixed inset-0 z-50 flex items-center justify-center px-4", children: [
3331
+ /* @__PURE__ */ jsx(
3332
+ "div",
3333
+ {
3334
+ className: `absolute inset-0 backdrop-blur-sm transition-opacity duration-200 ${isAnimating ? "opacity-100" : "opacity-0"}`,
3335
+ style: {
3336
+ backgroundColor: "rgba(0, 0, 0, 0.2)"
3337
+ },
3338
+ onClick: handleOverlayClick
3339
+ }
3340
+ ),
3341
+ /* @__PURE__ */ jsxs(
3342
+ "div",
3343
+ {
3344
+ className: `relative backdrop-blur-xl rounded-3xl shadow-2xl border p-8 max-w-md w-full mx-auto transition-all duration-200 ${isAnimating ? "opacity-100 scale-100" : "opacity-0 scale-95"}`,
3345
+ style: {
3346
+ backgroundColor: "var(--lm-bg-elevated)",
3347
+ borderColor: "var(--lm-border-default)",
3348
+ boxShadow: "var(--lm-shadow-xl)"
3349
+ },
3350
+ children: [
3351
+ /* @__PURE__ */ jsxs("div", { className: "text-center mb-6", children: [
3352
+ /* @__PURE__ */ jsx(
3353
+ "div",
3354
+ {
3355
+ className: "inline-flex items-center justify-center w-16 h-16 rounded-full mb-4",
3356
+ style: {
3357
+ backgroundColor: "var(--lm-gray-100)"
3358
+ },
3359
+ children: /* @__PURE__ */ jsx("span", { style: { color: "var(--lm-gray-600)" }, children: /* @__PURE__ */ jsx(QuestionIcon, {}) })
3360
+ }
3361
+ ),
3362
+ /* @__PURE__ */ jsx(
3363
+ "h3",
3364
+ {
3365
+ className: "text-xl font-semibold mb-2",
3366
+ style: {
3367
+ color: "var(--lm-text-primary)"
3368
+ },
3369
+ children: title
3370
+ }
3371
+ ),
3372
+ /* @__PURE__ */ jsx(
3373
+ "p",
3374
+ {
3375
+ className: "text-sm leading-relaxed",
3376
+ style: {
3377
+ color: "var(--lm-text-secondary)"
3378
+ },
3379
+ children: content
3380
+ }
3381
+ )
3382
+ ] }),
3383
+ /* @__PURE__ */ jsxs("div", { className: "flex space-x-3", children: [
3384
+ /* @__PURE__ */ jsx(
3385
+ "button",
3386
+ {
3387
+ onClick: onCancel,
3388
+ className: "flex-1 py-3 px-4 font-medium rounded-xl transition-all duration-200 hover:scale-[1.02] active:scale-[0.98]",
3389
+ style: {
3390
+ backgroundColor: "var(--lm-gray-100)",
3391
+ color: "var(--lm-text-primary)"
3392
+ },
3393
+ onMouseEnter: (e) => {
3394
+ e.currentTarget.style.backgroundColor = "var(--lm-gray-200)";
3395
+ },
3396
+ onMouseLeave: (e) => {
3397
+ e.currentTarget.style.backgroundColor = "var(--lm-gray-100)";
3398
+ },
3399
+ children: cancelText
3400
+ }
3401
+ ),
3402
+ /* @__PURE__ */ jsx(
3403
+ "button",
3404
+ {
3405
+ onClick: onConfirm,
3406
+ className: "flex-1 py-3 px-4 font-medium rounded-xl transition-all duration-200 hover:scale-[1.02] active:scale-[0.98]",
3407
+ style: getConfirmButtonStyles(),
3408
+ onMouseEnter: (e) => {
3409
+ const hoverStyles = getConfirmButtonHoverStyles();
3410
+ e.currentTarget.style.backgroundColor = (hoverStyles == null ? void 0 : hoverStyles.backgroundColor) || "";
3411
+ },
3412
+ onMouseLeave: (e) => {
3413
+ const normalStyles = getConfirmButtonStyles();
3414
+ e.currentTarget.style.backgroundColor = (normalStyles == null ? void 0 : normalStyles.backgroundColor) || "";
3415
+ },
3416
+ children: confirmText
3417
+ }
3418
+ )
3419
+ ] })
3420
+ ]
3421
+ }
3422
+ )
3423
+ ] });
3424
+ };
3425
+ const useConfirm = () => {
3426
+ const [visible, setVisible] = useState(false);
3427
+ const [config, setConfig] = useState(null);
3428
+ const [resolveRef, setResolveRef] = useState(null);
3429
+ const confirm = useCallback((options) => {
3430
+ return new Promise((resolve) => {
3431
+ setConfig(options);
3432
+ setVisible(true);
3433
+ setResolveRef(() => resolve);
3434
+ });
3435
+ }, []);
3436
+ const handleConfirm = useCallback(() => {
3437
+ setVisible(false);
3438
+ resolveRef == null ? void 0 : resolveRef(true);
3439
+ setResolveRef(null);
3440
+ }, [resolveRef]);
3441
+ const handleCancel = useCallback(() => {
3442
+ setVisible(false);
3443
+ resolveRef == null ? void 0 : resolveRef(false);
3444
+ setResolveRef(null);
3445
+ }, [resolveRef]);
3446
+ const ConfirmDialog = useCallback(() => {
3447
+ if (!config) return null;
3448
+ return /* @__PURE__ */ jsx(
3449
+ LMConfirm,
3450
+ {
3451
+ visible,
3452
+ ...config,
3453
+ onConfirm: handleConfirm,
3454
+ onCancel: handleCancel
3455
+ }
3456
+ );
3457
+ }, [visible, config, handleConfirm, handleCancel]);
3458
+ return {
3459
+ visible,
3460
+ config,
3461
+ confirm,
3462
+ ConfirmDialog
3463
+ };
3464
+ };
3465
+ const ArrowUpIcon = () => /* @__PURE__ */ jsx("svg", { className: "w-3 h-3", viewBox: "0 0 12 12", fill: "none", stroke: "currentColor", strokeWidth: 2, children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M6 10V2M6 2l4 4M6 2L2 6" }) });
3466
+ const ArrowDownIcon = () => /* @__PURE__ */ jsx("svg", { className: "w-3 h-3", viewBox: "0 0 12 12", fill: "none", stroke: "currentColor", strokeWidth: 2, children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M6 2v8M6 10l4-4M6 10l-4-4" }) });
3467
+ const MinusIcon = () => /* @__PURE__ */ jsx("svg", { className: "w-3 h-3", viewBox: "0 0 12 12", fill: "none", stroke: "currentColor", strokeWidth: 2, children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M2 6h8" }) });
3468
+ const LMStatCard = ({
3469
+ title,
3470
+ value,
3471
+ description,
3472
+ icon,
3473
+ trend,
3474
+ trendText,
3475
+ variant = "default",
3476
+ size = "md",
3477
+ clickable = false,
3478
+ onClick,
3479
+ className = "",
3480
+ prefix,
3481
+ suffix,
3482
+ bordered = true,
3483
+ shadow = true,
3484
+ compact = false
3485
+ }) => {
3486
+ const resolvedSize = clampComponentSize(size, COMPONENT_SIZE_ORDER);
3487
+ const iconSizeClasses = compact ? {
3488
+ xs: "w-4 h-4",
3489
+ sm: "w-5 h-5",
3490
+ md: "w-6 h-6",
3491
+ lg: "w-8 h-8",
3492
+ xl: "w-10 h-10",
3493
+ "2xl": "w-12 h-12"
3494
+ } : {
3495
+ xs: "w-5 h-5",
3496
+ sm: "w-6 h-6",
3497
+ md: "w-10 h-10",
3498
+ lg: "w-12 h-12",
3499
+ xl: "w-14 h-14",
3500
+ "2xl": "w-16 h-16"
3501
+ };
3502
+ const titleTextClasses = compact ? {
3503
+ xs: "text-[10px]",
3504
+ sm: "text-[10px]",
3505
+ md: "text-xs",
3506
+ lg: "text-sm",
3507
+ xl: "text-base",
3508
+ "2xl": "text-lg"
3509
+ } : {
3510
+ xs: "text-xs",
3511
+ sm: "text-xs",
3512
+ md: "text-sm",
3513
+ lg: "text-base",
3514
+ xl: "text-lg",
3515
+ "2xl": "text-xl"
3516
+ };
3517
+ const metaTextClasses = compact ? {
3518
+ xs: "text-[10px]",
3519
+ sm: "text-[10px]",
3520
+ md: "text-[10px]",
3521
+ lg: "text-[10px]",
3522
+ xl: "text-xs",
3523
+ "2xl": "text-xs"
3524
+ } : {
3525
+ xs: "text-xs",
3526
+ sm: "text-xs",
3527
+ md: "text-sm",
3528
+ lg: "text-sm",
3529
+ xl: "text-base",
3530
+ "2xl": "text-lg"
3531
+ };
3532
+ const descriptionTextClasses = {
3533
+ xs: "text-xs",
3534
+ sm: "text-xs",
3535
+ md: "text-xs",
3536
+ lg: "text-xs",
3537
+ xl: "text-xs",
3538
+ "2xl": "text-xs"
3539
+ };
3540
+ const valueTextClasses = compact ? {
3541
+ xs: "text-sm",
3542
+ sm: "text-base",
3543
+ md: "text-lg",
3544
+ lg: "text-xl",
3545
+ xl: "text-2xl",
3546
+ "2xl": "text-3xl"
3547
+ } : {
3548
+ xs: "text-lg",
3549
+ sm: "text-xl",
3550
+ md: "text-3xl",
3551
+ lg: "text-4xl",
3552
+ xl: "text-5xl",
3553
+ "2xl": "text-6xl"
3554
+ };
3555
+ const roundedClasses = "rounded-2xl";
3556
+ const borderClasses = bordered ? "border" : "";
3557
+ const shadowClasses = shadow ? "shadow-sm" : "";
3558
+ const clickableClasses = clickable ? "cursor-pointer transition-transform hover:scale-105" : "";
3559
+ const baseClassName = `
3560
+ ${SIZE_PADDING_CLASSES[resolvedSize]} ${roundedClasses} ${borderClasses} ${shadowClasses} ${clickableClasses}
3561
+ backdrop-blur-md transition-all duration-300
3562
+ ${className}
3563
+ `.trim().replace(/\s+/g, " ");
3564
+ const getCardStyles = () => {
3565
+ const baseStyles = {
3566
+ backgroundColor: "var(--lm-bg-elevated)",
3567
+ color: "var(--lm-text-primary)",
3568
+ borderColor: "var(--lm-border-default)",
3569
+ boxShadow: "var(--lm-shadow-sm)"
3570
+ };
3571
+ switch (variant) {
3572
+ case "primary":
3573
+ return {
3574
+ ...baseStyles,
3575
+ backgroundColor: "var(--lm-primary-50)",
3576
+ borderColor: "var(--lm-primary-200)"
3577
+ };
3578
+ case "success":
3579
+ return {
3580
+ ...baseStyles,
3581
+ backgroundColor: "var(--lm-success-50)",
3582
+ borderColor: "var(--lm-success-200)"
3583
+ };
3584
+ case "warning":
3585
+ return {
3586
+ ...baseStyles,
3587
+ backgroundColor: "var(--lm-warning-50)",
3588
+ borderColor: "var(--lm-warning-200)"
3589
+ };
3590
+ case "error":
3591
+ return {
3592
+ ...baseStyles,
3593
+ backgroundColor: "var(--lm-error-50)",
3594
+ borderColor: "var(--lm-error-200)"
3595
+ };
3596
+ case "info":
3597
+ return {
3598
+ ...baseStyles,
3599
+ backgroundColor: "var(--lm-gray-50)",
3600
+ borderColor: "var(--lm-gray-200)"
3601
+ };
3602
+ default:
3603
+ return baseStyles;
3604
+ }
3605
+ };
3606
+ const getHoverStyles = () => {
3607
+ if (!clickable) return {};
3608
+ switch (variant) {
3609
+ case "primary":
3610
+ return {
3611
+ backgroundColor: "var(--lm-primary-100)",
3612
+ borderColor: "var(--lm-primary-300)",
3613
+ boxShadow: "var(--lm-shadow-md)"
3614
+ };
3615
+ case "success":
3616
+ return {
3617
+ backgroundColor: "var(--lm-success-100)",
3618
+ borderColor: "var(--lm-success-300)",
3619
+ boxShadow: "var(--lm-shadow-md)"
3620
+ };
3621
+ case "warning":
3622
+ return {
3623
+ backgroundColor: "var(--lm-warning-100)",
3624
+ borderColor: "var(--lm-warning-300)",
3625
+ boxShadow: "var(--lm-shadow-md)"
3626
+ };
3627
+ case "error":
3628
+ return {
3629
+ backgroundColor: "var(--lm-error-100)",
3630
+ borderColor: "var(--lm-error-300)",
3631
+ boxShadow: "var(--lm-shadow-md)"
3632
+ };
3633
+ case "info":
3634
+ return {
3635
+ backgroundColor: "var(--lm-gray-100)",
3636
+ borderColor: "var(--lm-gray-300)",
3637
+ boxShadow: "var(--lm-shadow-md)"
3638
+ };
3639
+ default:
3640
+ return {
3641
+ backgroundColor: "var(--lm-bg-paper)",
3642
+ borderColor: "var(--lm-border-strong)",
3643
+ boxShadow: "var(--lm-shadow-md)"
3644
+ };
3645
+ }
3646
+ };
3647
+ const getIconStyles = () => {
3648
+ switch (variant) {
3649
+ case "primary":
3650
+ return {
3651
+ color: "var(--lm-primary-600)",
3652
+ backgroundColor: "var(--lm-primary-100)"
3653
+ };
3654
+ case "success":
3655
+ return {
3656
+ color: "var(--lm-success-600)",
3657
+ backgroundColor: "var(--lm-success-100)"
3658
+ };
3659
+ case "warning":
3660
+ return {
3661
+ color: "var(--lm-warning-600)",
3662
+ backgroundColor: "var(--lm-warning-100)"
3663
+ };
3664
+ case "error":
3665
+ return {
3666
+ color: "var(--lm-error-600)",
3667
+ backgroundColor: "var(--lm-error-100)"
3668
+ };
3669
+ case "info":
3670
+ return {
3671
+ color: "var(--lm-gray-600)",
3672
+ backgroundColor: "var(--lm-gray-100)"
3673
+ };
3674
+ default:
3675
+ return {
3676
+ color: "var(--lm-primary-600)",
3677
+ backgroundColor: "var(--lm-bg-paper)"
3678
+ };
3679
+ }
3680
+ };
3681
+ const getValueStyles = () => {
3682
+ switch (variant) {
3683
+ case "primary":
3684
+ return { color: "var(--lm-primary-700)" };
3685
+ case "success":
3686
+ return { color: "var(--lm-success-700)" };
3687
+ case "warning":
3688
+ return { color: "var(--lm-warning-700)" };
3689
+ case "error":
3690
+ return { color: "var(--lm-error-700)" };
3691
+ case "info":
3692
+ return { color: "var(--lm-gray-700)" };
3693
+ default:
3694
+ return { color: "var(--lm-text-primary)" };
3695
+ }
3696
+ };
3697
+ const getTrendStyles = () => {
3698
+ if (trend == null) return {};
3699
+ if (trend > 0) return { color: "var(--lm-success-600)" };
3700
+ if (trend < 0) return { color: "var(--lm-error-600)" };
3701
+ return { color: "var(--lm-text-secondary)" };
3702
+ };
3703
+ const getTrendIcon = () => {
3704
+ if (trend == null) return null;
3705
+ if (trend > 0) return /* @__PURE__ */ jsx(ArrowUpIcon, {});
3706
+ if (trend < 0) return /* @__PURE__ */ jsx(ArrowDownIcon, {});
3707
+ return /* @__PURE__ */ jsx(MinusIcon, {});
3708
+ };
3709
+ const handleKeyDown = (e) => {
3710
+ if (!clickable) return;
3711
+ if (e.key === "Enter" || e.key === " ") {
3712
+ e.preventDefault();
3713
+ onClick == null ? void 0 : onClick();
3714
+ }
3715
+ };
3716
+ return /* @__PURE__ */ jsx(
3717
+ "div",
3718
+ {
3719
+ className: baseClassName,
3720
+ style: getCardStyles(),
3721
+ onClick: clickable ? onClick : void 0,
3722
+ onKeyDown: handleKeyDown,
3723
+ onMouseEnter: (e) => {
3724
+ if (clickable) Object.assign(e.currentTarget.style, getHoverStyles());
3725
+ },
3726
+ onMouseLeave: (e) => {
3727
+ if (clickable) Object.assign(e.currentTarget.style, getCardStyles());
3728
+ },
3729
+ role: clickable ? "button" : void 0,
3730
+ tabIndex: clickable ? 0 : void 0,
3731
+ "aria-label": clickable ? title : void 0,
3732
+ children: /* @__PURE__ */ jsx("div", { className: "flex items-start justify-between overflow-hidden", children: /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
3733
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 mb-2 min-w-0", children: [
3734
+ icon && /* @__PURE__ */ jsx(
3735
+ "div",
3736
+ {
3737
+ className: `${iconSizeClasses[resolvedSize]} rounded-lg flex items-center justify-center flex-shrink-0`,
3738
+ style: getIconStyles(),
3739
+ children: icon
3740
+ }
3741
+ ),
3742
+ /* @__PURE__ */ jsx(
3743
+ "h3",
3744
+ {
3745
+ className: `${titleTextClasses[resolvedSize]} font-medium truncate`,
3746
+ style: { color: "var(--lm-text-secondary)" },
3747
+ title,
3748
+ children: title
3749
+ }
3750
+ )
3751
+ ] }),
3752
+ /* @__PURE__ */ jsxs(
3753
+ "div",
3754
+ {
3755
+ className: `flex items-baseline ${SIZE_GAP_CLASSES[resolvedSize]} min-w-0 overflow-hidden w-full`,
3756
+ children: [
3757
+ prefix && /* @__PURE__ */ jsx(
3758
+ "span",
3759
+ {
3760
+ className: `${metaTextClasses[resolvedSize]} flex-shrink-0`,
3761
+ style: { color: "var(--lm-text-secondary)" },
3762
+ children: prefix
3763
+ }
3764
+ ),
3765
+ /* @__PURE__ */ jsx(
3766
+ "span",
3767
+ {
3768
+ className: `font-bold ${valueTextClasses[resolvedSize]} overflow-hidden`,
3769
+ style: getValueStyles(),
3770
+ children: value
3771
+ }
3772
+ ),
3773
+ suffix && /* @__PURE__ */ jsx(
3774
+ "span",
3775
+ {
3776
+ className: `${metaTextClasses[resolvedSize]} flex-shrink-0`,
3777
+ style: { color: "var(--lm-text-secondary)" },
3778
+ children: suffix
3779
+ }
3780
+ )
3781
+ ]
3782
+ }
3783
+ ),
3784
+ description && /* @__PURE__ */ jsx(
3785
+ "p",
3786
+ {
3787
+ className: `${descriptionTextClasses[resolvedSize]} mt-1 truncate`,
3788
+ style: { color: "var(--lm-text-secondary)" },
3789
+ title: description,
3790
+ children: description
3791
+ }
3792
+ ),
3793
+ (trend != null || trendText) && /* @__PURE__ */ jsxs("div", { className: `flex items-center ${SIZE_GAP_CLASSES[resolvedSize]} mt-2`, children: [
3794
+ trend != null && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", style: getTrendStyles(), children: [
3795
+ getTrendIcon(),
3796
+ /* @__PURE__ */ jsxs("span", { className: "text-sm font-medium", children: [
3797
+ Math.abs(trend),
3798
+ "%"
3799
+ ] })
3800
+ ] }),
3801
+ trendText && /* @__PURE__ */ jsx("span", { className: "text-sm", style: { color: "var(--lm-text-secondary)" }, children: trendText })
3802
+ ] })
3803
+ ] }) })
3804
+ }
3805
+ );
3806
+ };
3807
+ function cn(...inputs) {
3808
+ return inputs.flat().filter((x) => typeof x === "string" && x.length > 0).join(" ");
3809
+ }
3810
+ export {
3811
+ COMPONENT_SIZE_ORDER,
3812
+ LMBadge,
3813
+ LMButton$1 as LMButton,
3814
+ LMCheckbox,
3815
+ LMConfirm,
3816
+ LMField,
3817
+ LMInput,
3818
+ LMMessage,
3819
+ LMMessageContainer,
3820
+ LMModal_default as LMModal,
3821
+ LMNumberInput,
3822
+ LMRadio,
3823
+ LMSearchInput,
3824
+ LMSelect,
3825
+ LMStatCard,
3826
+ LMSwitch,
3827
+ LMTable_default as LMTable,
3828
+ LMTextarea,
3829
+ LMTooltip,
3830
+ SIZE_BUTTON_CONFIG,
3831
+ SIZE_DISPLAY_CLASSES,
3832
+ SIZE_GAP_CLASSES,
3833
+ SIZE_HEADING_CLASSES,
3834
+ SIZE_ICON_CONFIG,
3835
+ SIZE_INPUT_CONFIG,
3836
+ SIZE_MODAL_CONFIG,
3837
+ SIZE_PADDING_CLASSES,
3838
+ SIZE_SELECTOR_CONFIG,
3839
+ SIZE_TABLE_CONFIG,
3840
+ SIZE_TEXT_CLASSES,
3841
+ SIZE_TOOLTIP_CONFIG,
3842
+ clampComponentSize,
3843
+ cn,
3844
+ useConfirm,
3845
+ useMessage
3846
+ };
3847
+ //# sourceMappingURL=index.js.map