@fangxinyan/lumina 0.4.0 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (199) hide show
  1. package/dist/Accordion.cjs +3 -3
  2. package/dist/Accordion.js +2 -2
  3. package/dist/Alert.cjs +3 -3
  4. package/dist/Alert.js +2 -2
  5. package/dist/AutoComplete.cjs +5 -5
  6. package/dist/AutoComplete.js +4 -4
  7. package/dist/Button.cjs +4 -4
  8. package/dist/Button.js +2 -2
  9. package/dist/Calendar.cjs +3 -3
  10. package/dist/Calendar.js +2 -2
  11. package/dist/Cascader.cjs +4 -4
  12. package/dist/Cascader.js +3 -3
  13. package/dist/Checkbox.cjs +4 -4
  14. package/dist/Checkbox.js +2 -2
  15. package/dist/ColorPicker.cjs +3 -3
  16. package/dist/ColorPicker.js +2 -2
  17. package/dist/CommandPalette.cjs +4 -4
  18. package/dist/CommandPalette.js +3 -3
  19. package/dist/Drawer.cjs +3 -3
  20. package/dist/Drawer.js +2 -2
  21. package/dist/Icon.cjs +3 -3
  22. package/dist/Icon.d.cts +1 -1
  23. package/dist/Icon.d.ts +1 -1
  24. package/dist/Icon.js +1 -1
  25. package/dist/Image.cjs +4 -4
  26. package/dist/Image.js +2 -2
  27. package/dist/Input.cjs +4 -4
  28. package/dist/Input.js +2 -2
  29. package/dist/InputNumber.cjs +4 -4
  30. package/dist/InputNumber.js +3 -3
  31. package/dist/Modal.cjs +4 -4
  32. package/dist/Modal.js +3 -3
  33. package/dist/Pagination.cjs +6 -6
  34. package/dist/Pagination.js +5 -5
  35. package/dist/Popover-DVGQGWX6.css +103 -0
  36. package/dist/Popover.cjs +3 -3
  37. package/dist/Popover.d.cts +23 -1
  38. package/dist/Popover.d.ts +23 -1
  39. package/dist/Popover.js +2 -2
  40. package/dist/Select.cjs +5 -5
  41. package/dist/Select.js +4 -4
  42. package/dist/{Slider-X4PVA65R.css → Slider-3JKA5EW6.css} +44 -25
  43. package/dist/Slider.cjs +2 -2
  44. package/dist/Slider.d.cts +8 -5
  45. package/dist/Slider.d.ts +8 -5
  46. package/dist/Slider.js +1 -1
  47. package/dist/Table.cjs +9 -9
  48. package/dist/Table.js +7 -7
  49. package/dist/Tag.cjs +4 -4
  50. package/dist/Tag.js +2 -2
  51. package/dist/Timeline-RHZAZKZ7.css +136 -0
  52. package/dist/Timeline.cjs +13 -0
  53. package/dist/Timeline.cjs.map +1 -0
  54. package/dist/Timeline.d.cts +38 -0
  55. package/dist/Timeline.d.ts +38 -0
  56. package/dist/Timeline.js +4 -0
  57. package/dist/Timeline.js.map +1 -0
  58. package/dist/{Toast-6PVSAXQ5.css → Toast-YSACW3EM.css} +2 -2
  59. package/dist/Toast.cjs +4 -4
  60. package/dist/Toast.js +2 -2
  61. package/dist/{Tooltip-ST24GY4S.css → Tooltip-DMKUPC24.css} +1 -0
  62. package/dist/Tooltip.cjs +3 -3
  63. package/dist/Tooltip.js +2 -2
  64. package/dist/Typography.cjs +7 -7
  65. package/dist/Typography.js +2 -2
  66. package/dist/{chunk-BCPAY65C.cjs → chunk-2D5VCIJZ.cjs} +7 -7
  67. package/dist/{chunk-BCPAY65C.cjs.map → chunk-2D5VCIJZ.cjs.map} +1 -1
  68. package/dist/{chunk-LLNEDEST.cjs → chunk-2OBQOEFD.cjs} +4 -4
  69. package/dist/{chunk-LLNEDEST.cjs.map → chunk-2OBQOEFD.cjs.map} +1 -1
  70. package/dist/chunk-2TZ2R7L2.js +235 -0
  71. package/dist/chunk-2TZ2R7L2.js.map +1 -0
  72. package/dist/{chunk-N73JGXYZ.cjs → chunk-3ES5QPAF.cjs} +4 -4
  73. package/dist/{chunk-N73JGXYZ.cjs.map → chunk-3ES5QPAF.cjs.map} +1 -1
  74. package/dist/{chunk-YCHUHMNP.cjs → chunk-3KQKEE5O.cjs} +5 -4
  75. package/dist/chunk-3KQKEE5O.cjs.map +1 -0
  76. package/dist/{chunk-RZ2E3XEU.cjs → chunk-3XIDJEYR.cjs} +21 -6
  77. package/dist/chunk-3XIDJEYR.cjs.map +1 -0
  78. package/dist/{chunk-IOWREUEP.js → chunk-3YYOYDKI.js} +4 -4
  79. package/dist/{chunk-IOWREUEP.js.map → chunk-3YYOYDKI.js.map} +1 -1
  80. package/dist/{chunk-PKXXR76Q.js → chunk-4ADDAZK3.js} +3 -3
  81. package/dist/{chunk-PKXXR76Q.js.map → chunk-4ADDAZK3.js.map} +1 -1
  82. package/dist/{chunk-TZLM5GF4.js → chunk-5SJJI3HL.js} +4 -4
  83. package/dist/{chunk-TZLM5GF4.js.map → chunk-5SJJI3HL.js.map} +1 -1
  84. package/dist/{chunk-2ENTRT7R.cjs → chunk-AJEF2ZB7.cjs} +16 -6
  85. package/dist/chunk-AJEF2ZB7.cjs.map +1 -0
  86. package/dist/{chunk-V2DIQ3RH.js → chunk-ANAQER3T.js} +21 -6
  87. package/dist/chunk-ANAQER3T.js.map +1 -0
  88. package/dist/{chunk-FXQGPHK2.js → chunk-AZRJZM7W.js} +3 -3
  89. package/dist/{chunk-FXQGPHK2.js.map → chunk-AZRJZM7W.js.map} +1 -1
  90. package/dist/{chunk-3BZ47QNV.cjs → chunk-BIXW4ZYW.cjs} +7 -7
  91. package/dist/{chunk-3BZ47QNV.cjs.map → chunk-BIXW4ZYW.cjs.map} +1 -1
  92. package/dist/{chunk-IJA26LRY.cjs → chunk-BPDWBY6Y.cjs} +4 -4
  93. package/dist/{chunk-IJA26LRY.cjs.map → chunk-BPDWBY6Y.cjs.map} +1 -1
  94. package/dist/{chunk-77TZHI76.cjs → chunk-D26YHP2Y.cjs} +7 -7
  95. package/dist/{chunk-77TZHI76.cjs.map → chunk-D26YHP2Y.cjs.map} +1 -1
  96. package/dist/{chunk-T4PI2ZX7.cjs → chunk-D3GZSL2B.cjs} +16 -17
  97. package/dist/chunk-D3GZSL2B.cjs.map +1 -0
  98. package/dist/{chunk-VQBZKRIB.cjs → chunk-DF5K2BZ2.cjs} +6 -6
  99. package/dist/{chunk-VQBZKRIB.cjs.map → chunk-DF5K2BZ2.cjs.map} +1 -1
  100. package/dist/{chunk-7M7NAMR5.js → chunk-DLGFIRVW.js} +14 -4
  101. package/dist/chunk-DLGFIRVW.js.map +1 -0
  102. package/dist/{chunk-6Z24VO3K.js → chunk-E7UQSFKF.js} +3 -3
  103. package/dist/{chunk-6Z24VO3K.js.map → chunk-E7UQSFKF.js.map} +1 -1
  104. package/dist/{chunk-KW7Z4IQC.js → chunk-FLPHVK45.js} +3 -3
  105. package/dist/{chunk-KW7Z4IQC.js.map → chunk-FLPHVK45.js.map} +1 -1
  106. package/dist/{chunk-WUOFJPZ4.js → chunk-GB5NAXBP.js} +3 -3
  107. package/dist/{chunk-WUOFJPZ4.js.map → chunk-GB5NAXBP.js.map} +1 -1
  108. package/dist/{chunk-SMHXSEBD.cjs → chunk-GT45MQAK.cjs} +7 -7
  109. package/dist/{chunk-SMHXSEBD.cjs.map → chunk-GT45MQAK.cjs.map} +1 -1
  110. package/dist/{chunk-TZXEZFCI.cjs → chunk-H2QTLV5T.cjs} +5 -5
  111. package/dist/{chunk-TZXEZFCI.cjs.map → chunk-H2QTLV5T.cjs.map} +1 -1
  112. package/dist/{chunk-FFZLSY2N.js → chunk-HHPYY4LH.js} +4 -4
  113. package/dist/{chunk-FFZLSY2N.js.map → chunk-HHPYY4LH.js.map} +1 -1
  114. package/dist/{chunk-XYVJ3FBQ.cjs → chunk-I7UJA6RM.cjs} +5 -5
  115. package/dist/{chunk-XYVJ3FBQ.cjs.map → chunk-I7UJA6RM.cjs.map} +1 -1
  116. package/dist/{chunk-YFBHVTKN.cjs → chunk-IJIQ4H6C.cjs} +7 -7
  117. package/dist/{chunk-YFBHVTKN.cjs.map → chunk-IJIQ4H6C.cjs.map} +1 -1
  118. package/dist/{chunk-LXNR6TQK.js → chunk-ILVNMES2.js} +3 -3
  119. package/dist/{chunk-LXNR6TQK.js.map → chunk-ILVNMES2.js.map} +1 -1
  120. package/dist/{chunk-JXHMJUVI.js → chunk-JELHUUM5.js} +3 -3
  121. package/dist/{chunk-JXHMJUVI.js.map → chunk-JELHUUM5.js.map} +1 -1
  122. package/dist/{chunk-CTYW42GG.js → chunk-JQZFOIX6.js} +6 -6
  123. package/dist/{chunk-CTYW42GG.js.map → chunk-JQZFOIX6.js.map} +1 -1
  124. package/dist/{chunk-I7WLFADD.js → chunk-LWN2PXW7.js} +3 -3
  125. package/dist/{chunk-I7WLFADD.js.map → chunk-LWN2PXW7.js.map} +1 -1
  126. package/dist/{chunk-I2HHC6QW.js → chunk-N5W6XJI2.js} +3 -3
  127. package/dist/{chunk-I2HHC6QW.js.map → chunk-N5W6XJI2.js.map} +1 -1
  128. package/dist/chunk-N6ZLZUBF.cjs +257 -0
  129. package/dist/chunk-N6ZLZUBF.cjs.map +1 -0
  130. package/dist/chunk-P2AV5BD7.cjs +137 -0
  131. package/dist/chunk-P2AV5BD7.cjs.map +1 -0
  132. package/dist/{chunk-ZFJHUOFU.js → chunk-P4XPESR2.js} +4 -4
  133. package/dist/{chunk-ZFJHUOFU.js.map → chunk-P4XPESR2.js.map} +1 -1
  134. package/dist/{chunk-AESLEYST.js → chunk-RJNGXR5Y.js} +4 -4
  135. package/dist/{chunk-AESLEYST.js.map → chunk-RJNGXR5Y.js.map} +1 -1
  136. package/dist/chunk-S3NIRNWM.js +86 -0
  137. package/dist/chunk-S3NIRNWM.js.map +1 -0
  138. package/dist/{chunk-HJIKU6MF.cjs → chunk-S7RFIMA3.cjs} +4 -4
  139. package/dist/{chunk-HJIKU6MF.cjs.map → chunk-S7RFIMA3.cjs.map} +1 -1
  140. package/dist/chunk-TAYFI4RG.cjs +108 -0
  141. package/dist/chunk-TAYFI4RG.cjs.map +1 -0
  142. package/dist/{chunk-OZVPJWXO.cjs → chunk-TCPTBLDV.cjs} +5 -5
  143. package/dist/{chunk-OZVPJWXO.cjs.map → chunk-TCPTBLDV.cjs.map} +1 -1
  144. package/dist/{chunk-E62JFAHW.js → chunk-TGUDT3GK.js} +4 -4
  145. package/dist/{chunk-E62JFAHW.js.map → chunk-TGUDT3GK.js.map} +1 -1
  146. package/dist/{chunk-XCYE4OQV.js → chunk-TMRSI543.js} +3 -3
  147. package/dist/{chunk-XCYE4OQV.js.map → chunk-TMRSI543.js.map} +1 -1
  148. package/dist/{chunk-RWHWEQQX.cjs → chunk-U7TAQLPN.cjs} +6 -6
  149. package/dist/{chunk-RWHWEQQX.cjs.map → chunk-U7TAQLPN.cjs.map} +1 -1
  150. package/dist/chunk-UEHONGPZ.js +115 -0
  151. package/dist/chunk-UEHONGPZ.js.map +1 -0
  152. package/dist/{chunk-NN7WMXY4.cjs → chunk-UUY7EDVJ.cjs} +4 -4
  153. package/dist/{chunk-NN7WMXY4.cjs.map → chunk-UUY7EDVJ.cjs.map} +1 -1
  154. package/dist/{chunk-OM76QWUN.js → chunk-UXABXEWT.js} +3 -3
  155. package/dist/{chunk-OM76QWUN.js.map → chunk-UXABXEWT.js.map} +1 -1
  156. package/dist/{chunk-MDQNUKCP.cjs → chunk-V6466VMN.cjs} +14 -14
  157. package/dist/{chunk-MDQNUKCP.cjs.map → chunk-V6466VMN.cjs.map} +1 -1
  158. package/dist/{chunk-O7C6S644.js → chunk-WBL7LOIH.js} +3 -3
  159. package/dist/{chunk-O7C6S644.js.map → chunk-WBL7LOIH.js.map} +1 -1
  160. package/dist/{chunk-RQV7SMIZ.cjs → chunk-WKNVNN2K.cjs} +5 -5
  161. package/dist/{chunk-RQV7SMIZ.cjs.map → chunk-WKNVNN2K.cjs.map} +1 -1
  162. package/dist/{chunk-HXSAH4Y6.cjs → chunk-WR3FML2W.cjs} +7 -7
  163. package/dist/{chunk-HXSAH4Y6.cjs.map → chunk-WR3FML2W.cjs.map} +1 -1
  164. package/dist/{chunk-QOGROEVD.js → chunk-X3JG3IR6.js} +6 -5
  165. package/dist/chunk-X3JG3IR6.js.map +1 -0
  166. package/dist/{chunk-6XZ362VL.js → chunk-XT7RXXOE.js} +6 -7
  167. package/dist/chunk-XT7RXXOE.js.map +1 -0
  168. package/dist/{chunk-WVBFQB26.cjs → chunk-ZSR5JSYZ.cjs} +8 -8
  169. package/dist/{chunk-WVBFQB26.cjs.map → chunk-ZSR5JSYZ.cjs.map} +1 -1
  170. package/dist/index.cjs +67 -62
  171. package/dist/index.cjs.map +1 -1
  172. package/dist/index.d.cts +3 -2
  173. package/dist/index.d.ts +3 -2
  174. package/dist/index.js +27 -26
  175. package/dist/index.js.map +1 -1
  176. package/dist/styles.css +124 -29
  177. package/docs/llms/form.md +26 -0
  178. package/docs/llms/popover.md +138 -6
  179. package/docs/llms/slider.md +13 -2
  180. package/docs/llms/timeline.md +140 -0
  181. package/docs/llms.md +5 -4
  182. package/package.json +5 -1
  183. package/dist/Popover-NYEKT5CQ.css +0 -10
  184. package/dist/chunk-2ENTRT7R.cjs.map +0 -1
  185. package/dist/chunk-3UU2PUK4.js +0 -66
  186. package/dist/chunk-3UU2PUK4.js.map +0 -1
  187. package/dist/chunk-6XZ362VL.js.map +0 -1
  188. package/dist/chunk-7M7NAMR5.js.map +0 -1
  189. package/dist/chunk-B5JH7NRZ.cjs +0 -133
  190. package/dist/chunk-B5JH7NRZ.cjs.map +0 -1
  191. package/dist/chunk-O2HMH5BI.cjs +0 -88
  192. package/dist/chunk-O2HMH5BI.cjs.map +0 -1
  193. package/dist/chunk-QJGKI2BD.js +0 -111
  194. package/dist/chunk-QJGKI2BD.js.map +0 -1
  195. package/dist/chunk-QOGROEVD.js.map +0 -1
  196. package/dist/chunk-RZ2E3XEU.cjs.map +0 -1
  197. package/dist/chunk-T4PI2ZX7.cjs.map +0 -1
  198. package/dist/chunk-V2DIQ3RH.js.map +0 -1
  199. package/dist/chunk-YCHUHMNP.cjs.map +0 -1
package/dist/styles.css CHANGED
@@ -592,14 +592,23 @@ input, textarea, select { font-family: inherit; color: inherit; }
592
592
  /* ============ Slider ============ */
593
593
  .slider {
594
594
  position: relative;
595
- height: 36px;
596
595
  width: 100%;
597
596
  display: flex;
598
597
  align-items: center;
598
+ gap: 10px;
599
599
  cursor: pointer;
600
+ min-height: 36px;
600
601
  }
601
602
  .slider.has-marks { padding-bottom: 26px; }
602
603
  .slider.disabled { opacity: 0.5; cursor: not-allowed; }
604
+ /* Rail: positioning context for track + thumbs + marks */
605
+ .slider-rail {
606
+ position: relative;
607
+ flex: 1 1 0%;
608
+ height: 36px;
609
+ display: flex;
610
+ align-items: center;
611
+ }
603
612
  .slider-track {
604
613
  position: relative;
605
614
  width: 100%;
@@ -607,7 +616,8 @@ input, textarea, select { font-family: inherit; color: inherit; }
607
616
  border-radius: 999px;
608
617
  background: var(--bg);
609
618
  box-shadow: var(--neu-in-sm);
610
- overflow: hidden;
619
+ touch-action: none;
620
+ z-index: 1;
611
621
  }
612
622
  .slider-fill {
613
623
  position: absolute;
@@ -616,6 +626,7 @@ input, textarea, select { font-family: inherit; color: inherit; }
616
626
  box-shadow: 0 0 12px var(--accent-glow);
617
627
  border-radius: 999px;
618
628
  transition: left var(--dur-fast) var(--ease), right var(--dur-fast) var(--ease);
629
+ pointer-events: none;
619
630
  }
620
631
  .slider-thumb {
621
632
  position: absolute;
@@ -627,42 +638,42 @@ input, textarea, select { font-family: inherit; color: inherit; }
627
638
  transform: translate(-50%, -50%);
628
639
  transition: all var(--dur-fast) var(--ease);
629
640
  display: grid; place-items: center;
630
- pointer-events: none;
641
+ z-index: 3;
642
+ outline: none;
643
+ touch-action: none;
631
644
  }
632
- .slider.has-marks .slider-thumb { top: calc(50% - 13px); }
633
- .slider.has-marks .slider-track { margin-top: -26px; }
634
645
  .slider-thumb::after {
635
646
  content: "";
636
647
  width: 6px; height: 6px;
637
648
  border-radius: 999px;
638
- background: var(--accent);
649
+ background: var(--slider-thumb-color, var(--accent));
650
+ }
651
+ .slider-thumb:focus-visible {
652
+ box-shadow: var(--neu-out-sm), 0 0 0 3px var(--accent-glow);
639
653
  }
640
654
  .slider:hover .slider-thumb { transform: translate(-50%, -50%) scale(1.08); }
641
- .slider input[type="range"] {
642
- position: absolute;
643
- inset: 0;
644
- width: 100%; height: 100%;
645
- opacity: 0;
646
- cursor: inherit;
647
- margin: 0;
648
- pointer-events: auto;
655
+ .slider-value {
656
+ font-family: var(--font-mono);
657
+ font-size: 12px;
658
+ color: var(--accent-ink);
659
+ flex-shrink: 0;
660
+ white-space: nowrap;
649
661
  }
650
- /* In range mode (two stacked inputs), split the hit zones by half so the user can drag either thumb */
651
- .slider input[type="range"]:nth-of-type(1):not(:only-of-type) { right: 50%; }
652
- .slider input[type="range"]:nth-of-type(2) { left: 50%; }
653
- .slider.has-marks input[type="range"] { height: calc(100% - 26px); }
654
- .slider-value { font-family: var(--font-mono); font-size: 12px; color: var(--accent-ink); margin-left: 10px; }
662
+ /* Tone variants */
663
+ .slider.success .slider-thumb { --slider-thumb-color: var(--success); }
655
664
  .slider.success .slider-fill { background: linear-gradient(90deg, color-mix(in oklch, var(--success) 70%, white), var(--success)); box-shadow: 0 0 10px color-mix(in oklch, var(--success) 35%, transparent); }
656
- .slider.success .slider-thumb::after { background: var(--success); }
665
+ .slider.success .slider-thumb:focus-visible { box-shadow: var(--neu-out-sm), 0 0 0 3px color-mix(in oklch, var(--success) 35%, transparent); }
666
+ .slider.warning .slider-thumb { --slider-thumb-color: var(--warning); }
657
667
  .slider.warning .slider-fill { background: linear-gradient(90deg, color-mix(in oklch, var(--warning) 70%, white), var(--warning)); box-shadow: 0 0 10px color-mix(in oklch, var(--warning) 35%, transparent); }
658
- .slider.warning .slider-thumb::after { background: var(--warning); }
668
+ .slider.warning .slider-thumb:focus-visible { box-shadow: var(--neu-out-sm), 0 0 0 3px color-mix(in oklch, var(--warning) 35%, transparent); }
669
+ .slider.danger .slider-thumb { --slider-thumb-color: var(--danger); }
659
670
  .slider.danger .slider-fill { background: linear-gradient(90deg, color-mix(in oklch, var(--danger) 70%, white), var(--danger)); box-shadow: 0 0 10px color-mix(in oklch, var(--danger) 35%, transparent); }
660
- .slider.danger .slider-thumb::after { background: var(--danger); }
671
+ .slider.danger .slider-thumb:focus-visible { box-shadow: var(--neu-out-sm), 0 0 0 3px color-mix(in oklch, var(--danger) 35%, transparent); }
661
672
  /* Marks */
662
673
  .slider-marks {
663
674
  position: absolute;
664
675
  left: 0; right: 0;
665
- bottom: 0;
676
+ bottom: -26px;
666
677
  height: 22px;
667
678
  pointer-events: none;
668
679
  }
@@ -684,8 +695,10 @@ input, textarea, select { font-family: inherit; color: inherit; }
684
695
  border-radius: 999px;
685
696
  background: var(--bg);
686
697
  box-shadow: var(--neu-in-sm);
687
- margin-top: -18px;
688
- position: relative;
698
+ position: absolute;
699
+ top: -12px;
700
+ left: 50%;
701
+ transform: translateX(-50%);
689
702
  z-index: 1;
690
703
  }
691
704
  .slider-mark.active .slider-mark-dot { background: var(--accent); box-shadow: 0 0 6px var(--accent-glow); }
@@ -1529,6 +1542,7 @@ input, textarea, select { font-family: inherit; color: inherit; }
1529
1542
  .tip-anchor {
1530
1543
  position: relative;
1531
1544
  display: inline-flex;
1545
+ align-self: flex-start;
1532
1546
  }
1533
1547
  .tip {
1534
1548
  background: var(--bg-sunken);
@@ -1563,7 +1577,7 @@ input, textarea, select { font-family: inherit; color: inherit; }
1563
1577
  box-shadow: var(--neu-float);
1564
1578
  padding: 12px 16px;
1565
1579
  min-width: 240px;
1566
- display: flex; align-items: flex-start; gap: 10px;
1580
+ display: flex; align-items: center; gap: 10px;
1567
1581
  font-size: 13px;
1568
1582
  pointer-events: auto;
1569
1583
  animation: toastIn var(--dur-slow) var(--ease);
@@ -1572,7 +1586,7 @@ input, textarea, select { font-family: inherit; color: inherit; }
1572
1586
  .toast.success { border-color: var(--success); }
1573
1587
  .toast.warning { border-color: var(--warning); }
1574
1588
  .toast.danger { border-color: var(--danger); }
1575
- .toast .toast-icon { color: var(--accent); margin-top: 2px; }
1589
+ .toast .toast-icon { color: var(--accent); flex-shrink: 0; }
1576
1590
  .toast.success .toast-icon { color: var(--success); }
1577
1591
  .toast.warning .toast-icon { color: var(--warning); }
1578
1592
  .toast.danger .toast-icon { color: var(--danger); }
@@ -1593,10 +1607,91 @@ input, textarea, select { font-family: inherit; color: inherit; }
1593
1607
  z-index: 1000;
1594
1608
  background: var(--bg);
1595
1609
  border-radius: var(--r-md);
1596
- padding: var(--gap-3);
1597
1610
  min-width: 220px;
1598
1611
  box-shadow: var(--neu-float);
1599
- animation: menuIn var(--dur) var(--ease);
1612
+ position: relative;
1613
+ }
1614
+ /*
1615
+ * Direction-aware entrance.
1616
+ * We animate `opacity` + `translate` (the standalone property, NOT `transform`)
1617
+ * so we don't clobber the inline `transform: translateX(-50%)` that useFloating
1618
+ * applies for cross-axis centering.
1619
+ */
1620
+ .popover-bottom { animation: popoverInDown var(--dur) var(--ease); }
1621
+ .popover-top { animation: popoverInUp var(--dur) var(--ease); }
1622
+ .popover-left { animation: popoverInLeft var(--dur) var(--ease); }
1623
+ .popover-right { animation: popoverInRight var(--dur) var(--ease); }
1624
+ @keyframes popoverInDown { from { opacity: 0; translate: 0 -6px; } }
1625
+ @keyframes popoverInUp { from { opacity: 0; translate: 0 6px; } }
1626
+ @keyframes popoverInLeft { from { opacity: 0; translate: 6px 0; } }
1627
+ @keyframes popoverInRight { from { opacity: 0; translate: -6px 0; } }
1628
+ /* ---- Header ---- */
1629
+ .popover-header {
1630
+ display: flex;
1631
+ align-items: center;
1632
+ justify-content: space-between;
1633
+ padding: var(--gap-3) var(--gap-3) 0;
1634
+ gap: var(--gap-2);
1635
+ }
1636
+ .popover-title {
1637
+ font-weight: 600;
1638
+ font-size: 14px;
1639
+ color: var(--fg);
1640
+ }
1641
+ .popover-close {
1642
+ all: unset;
1643
+ cursor: pointer;
1644
+ font-size: 16px;
1645
+ color: var(--fg-muted);
1646
+ line-height: 1;
1647
+ padding: 2px 4px;
1648
+ border-radius: var(--r-xs);
1649
+ transition: color var(--dur-fast) var(--ease);
1650
+ margin-left: auto;
1651
+ }
1652
+ .popover-close:hover {
1653
+ color: var(--fg);
1654
+ }
1655
+ /* ---- Body ---- */
1656
+ .popover-body {
1657
+ padding: var(--gap-3);
1658
+ }
1659
+ .popover-header + .popover-body {
1660
+ padding-top: var(--gap-2);
1661
+ }
1662
+ /* ---- Arrow ---- */
1663
+ .popover-arrow {
1664
+ position: absolute;
1665
+ width: 10px;
1666
+ height: 10px;
1667
+ background: var(--bg);
1668
+ box-shadow: 2px 2px 4px rgba(163, 177, 198, 0.2);
1669
+ transform: rotate(45deg);
1670
+ pointer-events: none;
1671
+ }
1672
+ .popover-arrow-bottom {
1673
+ top: -5px;
1674
+ left: 50%;
1675
+ margin-left: -5px;
1676
+ box-shadow: -2px -2px 4px rgba(163, 177, 198, 0.2);
1677
+ }
1678
+ .popover-arrow-top {
1679
+ bottom: -5px;
1680
+ left: 50%;
1681
+ margin-left: -5px;
1682
+ box-shadow: 2px 2px 4px rgba(163, 177, 198, 0.2);
1683
+ }
1684
+ .popover-arrow-left {
1685
+ right: -5px;
1686
+ top: 50%;
1687
+ margin-top: -5px;
1688
+ box-shadow: 2px -2px 4px rgba(163, 177, 198, 0.2);
1689
+ }
1690
+ .popover-arrow-right {
1691
+ left: -5px;
1692
+ top: 50%;
1693
+ margin-top: -5px;
1694
+ box-shadow: -2px 2px 4px rgba(163, 177, 198, 0.2);
1600
1695
  }
1601
1696
  /* ============ Alert ============ */
1602
1697
  .alert {
package/docs/llms/form.md CHANGED
@@ -52,6 +52,32 @@ Checkbox / Switch 的绑定属性不是 value,需要用 valuePropName 指定;对
52
52
  </Form.Item>
53
53
  ```
54
54
 
55
+ ### 实时值预览
56
+
57
+ onValuesChange 可以监听任何字段变化。下方面板会实时展示 form.getFieldsValue() 的结果。
58
+
59
+ ```tsx
60
+ <Form onValuesChange={(changed, all) => setSnapshot(all)}>
61
+ ...
62
+ </Form>
63
+ <pre>{JSON.stringify(snapshot, null, 2)}</pre>
64
+ ```
65
+
66
+ ### 横排复选 (嵌套 Form.Item)
67
+
68
+ 外层 Form.Item 只做布局(无 name),内层若干 Form.Item 各自绑定字段并加 noStyle。my-assistant 里 "新建角色" 弹窗用的就是这个模式。
69
+
70
+ ```tsx
71
+ <Form.Item className="checkbox-row">
72
+ <Form.Item name="addToHistory" valuePropName="checked" initialValue={true} noStyle>
73
+ <Checkbox label="添加到登录列表" />
74
+ </Form.Item>
75
+ <Form.Item name="setAsLast" valuePropName="checked" initialValue={false} noStyle>
76
+ <Checkbox label="设为最近登录" />
77
+ </Form.Item>
78
+ </Form.Item>
79
+ ```
80
+
55
81
  ### 命令式 API
56
82
 
57
83
  通过 Form.useForm() 拿到实例,外部可主动 setFieldsValue / validateFields / resetFields。
@@ -1,6 +1,6 @@
1
1
  # Popover 气泡卡片
2
2
 
3
- > 比 Tooltip 更丰富,可承载交互内容。
3
+ > 比 Tooltip 更丰富,可承载交互内容。
4
4
 
5
5
  ## 导入
6
6
 
@@ -10,11 +10,137 @@ import { Popover } from "@fangxinyan/lumina";
10
10
 
11
11
  ## 示例
12
12
 
13
- ### 基础
13
+ ### 基础用法
14
+
15
+ 点击触发,弹出气泡卡片
16
+
17
+ ```tsx
18
+ <Row gap={24}>
19
+ <Popover
20
+ title="确认删除?"
21
+ content={
22
+ <div>
23
+ <div style={{ color: "var(--fg-muted)", fontSize: 13, marginBottom: 12 }}>
24
+ 删除后无法恢复。
25
+ </div>
26
+ <Row gap={6}>
27
+ <Button size="sm" variant="ghost">取消</Button>
28
+ <Button size="sm" variant="danger">删除</Button>
29
+ </Row>
30
+ </div>
31
+ }
32
+ >
33
+ <Button variant="danger" icon="trash">删除项目</Button>
34
+ </Popover>
35
+
36
+ <Popover
37
+ placement="right"
38
+ content={
39
+ <div style={{ display: "flex", alignItems: "center", gap: 10, minWidth: 160 }}>
40
+ <Avatar alt="金" size="sm" />
41
+ <div>
42
+ <div style={{ fontSize: 13, fontWeight: 600 }}>金伟</div>
43
+ <div style={{ fontSize: 11, color: "var(--fg-muted)" }}>设计总监</div>
44
+ </div>
45
+ </div>
46
+ }
47
+ >
48
+ <Avatar alt="金" />
49
+ </Popover>
50
+ </Row>
51
+ ```
52
+
53
+ ### 四方向
54
+
55
+ 支持 top / bottom / left / right 四个方向
56
+
57
+ ```tsx
58
+ <div style={{ display: "flex", flexWrap: "wrap", justifyContent: "center", gap: 12 }}>
59
+ <Popover placement="top" arrow content={<div>上方弹出内容</div>}>
60
+ <Button variant="ghost">上方</Button>
61
+ </Popover>
62
+ <Popover placement="bottom" arrow content={<div>下方弹出内容</div>}>
63
+ <Button variant="ghost">下方</Button>
64
+ </Popover>
65
+ <Popover placement="left" arrow content={<div>左侧弹出内容</div>}>
66
+ <Button variant="ghost">左侧</Button>
67
+ </Popover>
68
+ <Popover placement="right" arrow content={<div>右侧弹出内容</div>}>
69
+ <Button variant="ghost">右侧</Button>
70
+ </Popover>
71
+ </div>
72
+ ```
73
+
74
+ ### 箭头
75
+
76
+ arrow 属性添加指向触发元素的小箭头
77
+
78
+ ```tsx
79
+ <Popover
80
+ arrow
81
+ title="系统通知"
82
+ content={<div style={{ color: "var(--fg-muted)", fontSize: 13 }}>你有 3 条未读消息。</div>}
83
+ >
84
+ <Button icon="bell">消息</Button>
85
+ </Popover>
86
+ ```
87
+
88
+ ### 可关闭
89
+
90
+ closable 显示关闭按钮,适合信息提示场景
91
+
92
+ ```tsx
93
+ <Popover
94
+ closable
95
+ arrow
96
+ title="注意事项"
97
+ content={<div style={{ color: "var(--fg-muted)", fontSize: 13 }}>此操作需要管理员权限才能执行。</div>}
98
+ >
99
+ <Button icon="alert">权限</Button>
100
+ </Popover>
101
+ ```
102
+
103
+ ### Hover 触发
104
+
105
+ trigger="hover" 鼠标悬停触发
106
+
107
+ ```tsx
108
+ <Popover
109
+ trigger="hover"
110
+ arrow
111
+ content={
112
+ <div style={{ display: "flex", alignItems: "center", gap: 10, minWidth: 160 }}>
113
+ <Avatar alt="云" size="sm" />
114
+ <div>
115
+ <div style={{ fontSize: 13, fontWeight: 600 }}>云曦</div>
116
+ <div style={{ fontSize: 11, color: "var(--fg-muted)" }}>前端工程师</div>
117
+ </div>
118
+ </div>
119
+ }
120
+ >
121
+ <Avatar alt="云" />
122
+ </Popover>
123
+ ```
124
+
125
+ ### 表单内容
126
+
127
+ 气泡内可放置表单等复杂交互
14
128
 
15
129
  ```tsx
16
- <Popover content={<>...</>}>
17
- <Button>触发</Button>
130
+ <Popover
131
+ title="快速备注"
132
+ closable
133
+ arrow
134
+ content={
135
+ <div style={{ display: "flex", flexDirection: "column", gap: 10 }}>
136
+ <Input placeholder="输入备注..." />
137
+ <div style={{ display: "flex", justifyContent: "flex-end", gap: 6 }}>
138
+ <Button size="sm">保存</Button>
139
+ </div>
140
+ </div>
141
+ }
142
+ >
143
+ <Button icon="edit">备注</Button>
18
144
  </Popover>
19
145
  ```
20
146
 
@@ -25,9 +151,15 @@ import { Popover } from "@fangxinyan/lumina";
25
151
  | Prop | 类型 | 默认 | 说明 |
26
152
  | --- | --- | --- | --- |
27
153
  | content \* | `ReactNode` | — | 浮层内容 |
28
- | placement | `"top" | "bottom" | "left" | "right"` | `"bottom"` | 位置 |
154
+ | title | `ReactNode` | — | 标题 |
155
+ | placement | `"top" | "bottom" | "left" | "right"` | `"bottom"` | 弹出位置 |
29
156
  | trigger | `"click" | "hover"` | `"click"` | 触发方式 |
30
- | open / defaultOpen / onOpenChange | `—` | — | 受控显示 |
157
+ | arrow | `boolean` | `false` | 显示箭头 |
158
+ | closable | `boolean` | `false` | 显示关闭按钮 |
159
+ | width | `number | "auto"` | — | 面板宽度,"auto" 自适应 |
160
+ | open | `boolean` | — | 受控显示状态 |
161
+ | defaultOpen | `boolean` | `false` | 非受控初始状态 |
162
+ | onOpenChange | `(open: boolean) => void` | — | 显示状态变化回调 |
31
163
 
32
164
 
33
165
  ---
@@ -41,14 +41,24 @@ const [v, setV] = useState<[number, number]>([20, 70]);
41
41
  <Slider range value={v} onChange={setV} showValue />
42
42
  ```
43
43
 
44
- ### 刻度标记
44
+ ### 渐变色
45
45
 
46
- marks 提供可点击刻度,点击即可跳到该值。
46
+ colors 传入颜色数组,填充和滑块圆点会按当前位置动态插值。
47
+
48
+ ```tsx
49
+ <Slider defaultValue={60} showValue
50
+ colors={["#3b82f6", "#22c55e", "#eab308", "#ef4444"]} />
51
+ ```
52
+
53
+ ### 刻度标记 + 渐变
54
+
55
+ marks 配合 colors 可直观表达冷暖等语义。
47
56
 
48
57
  ```tsx
49
58
  <Slider
50
59
  defaultValue={37}
51
60
  marks={{ 0: "0°C", 26: "冷", 37: "正常", 100: "100°C" }}
61
+ colors={["#3b82f6", "#22c55e", "#eab308", "#ef4444"]}
52
62
  />
53
63
  ```
54
64
 
@@ -64,6 +74,7 @@ marks 提供可点击刻度,点击即可跳到该值。
64
74
  | range | `boolean` | `false` | 是否为双滑块区间模式 |
65
75
  | marks | `Record<number, ReactNode>` | — | 刻度,点击可跳到对应值 |
66
76
  | tone | `"accent" | "success" | "warning" | "danger"` | `"accent"` | 色调 |
77
+ | colors | `string[]` | — | 渐变色数组,按位置插值;覆盖 tone |
67
78
  | showValue | `boolean` | `false` | 显示数值 |
68
79
  | disabled | `boolean` | `false` | 禁用 |
69
80
 
@@ -0,0 +1,140 @@
1
+ # Timeline 时间线
2
+
3
+ > 垂直时间线,支持等待状态、自定义圆点、交替布局
4
+
5
+ ## 示例
6
+
7
+ ### 基础用法
8
+
9
+ 最简单的时间线
10
+
11
+ ```tsx
12
+ <Timeline
13
+ items={[
14
+ { children: "创建项目 2024-01-01" },
15
+ { children: "初始化仓库 2024-01-05" },
16
+ { children: "发布 v0.1.0 2024-02-01" },
17
+ { children: "里程碑达成 2024-03-15" },
18
+ ]}
19
+ />
20
+ ```
21
+
22
+ ### 彩色节点
23
+
24
+ 通过 color 区分不同状态
25
+
26
+ ```tsx
27
+ <Timeline
28
+ items={[
29
+ { children: "成功部署", color: "success" },
30
+ { children: "告警通知", color: "warning" },
31
+ { children: "构建失败", color: "danger" },
32
+ { children: "信息更新", color: "info" },
33
+ ]}
34
+ />
35
+ ```
36
+
37
+ ### 等待状态
38
+
39
+ pending 属性展示加载中的末尾节点,适合表示流程尚未结束
40
+
41
+ ```tsx
42
+ <Timeline
43
+ pending
44
+ pendingContent="部署中..."
45
+ items={[
46
+ { children: "提交代码 10:21", color: "success" },
47
+ { children: "代码审查通过 10:45", color: "success" },
48
+ { children: "CI 构建完成 11:02", color: "success" },
49
+ ]}
50
+ />
51
+ ```
52
+
53
+ ### 自定义等待图标
54
+
55
+ pending 传入 ReactNode 自定义等待指示器
56
+
57
+ ```tsx
58
+ <Timeline
59
+ pending={<Icon name="clock" size={14} />}
60
+ pendingContent="等待审批..."
61
+ items={[
62
+ { children: "提交申请" },
63
+ { children: "部门审核通过" },
64
+ ]}
65
+ />
66
+ ```
67
+
68
+ ### 自定义圆点
69
+
70
+ 通过 dot 字段自定义每个节点的图标
71
+
72
+ ```tsx
73
+ <Timeline
74
+ items={[
75
+ { children: "项目创建", dot: <Icon name="folder" size={14} /> },
76
+ { children: "代码提交", dot: <Icon name="code" size={14} /> },
77
+ { children: "发布上线", dot: <Icon name="zap" size={14} /> },
78
+ ]}
79
+ />
80
+ ```
81
+
82
+ ### 交替模式
83
+
84
+ mode="alternate" 让内容交替出现在两侧
85
+
86
+ ```tsx
87
+ <Timeline
88
+ mode="alternate"
89
+ items={[
90
+ { children: "创建项目", label: "2024-01" },
91
+ { children: "完成设计稿", label: "2024-02" },
92
+ { children: "开发完成", label: "2024-03" },
93
+ { children: "发布上线", label: "2024-04" },
94
+ ]}
95
+ />
96
+ ```
97
+
98
+ ### 倒序
99
+
100
+ reverse 属性将时间线反转,最新的事件在最上面
101
+
102
+ ```tsx
103
+ <Timeline
104
+ reverse
105
+ pending
106
+ pendingContent="进行中..."
107
+ items={[
108
+ { children: "第一步:需求确认", color: "success" },
109
+ { children: "第二步:开发中", color: "success" },
110
+ { children: "第三步:测试", color: "warning" },
111
+ ]}
112
+ />
113
+ ```
114
+
115
+ ## API
116
+
117
+ **Timeline**
118
+
119
+ | Prop | 类型 | 默认 | 说明 |
120
+ | --- | --- | --- | --- |
121
+ | items \* | `TimelineItemConfig[]` | — | 时间线节点数组 |
122
+ | pending | `boolean | ReactNode` | `false` | 显示末尾等待节点;true 显示默认 spinner,传 ReactNode 自定义 |
123
+ | pendingContent | `ReactNode` | `"加载中..."` | 等待节点的文字内容 |
124
+ | mode | `"left" | "right" | "alternate"` | `"left"` | 布局模式 |
125
+ | reverse | `boolean` | `false` | 反转节点顺序 |
126
+
127
+
128
+ **TimelineItemConfig**
129
+
130
+ | Prop | 类型 | 默认 | 说明 |
131
+ | --- | --- | --- | --- |
132
+ | key | `string` | — | 唯一标识 |
133
+ | children | `ReactNode` | — | 节点内容 |
134
+ | label | `ReactNode` | — | 对侧标签(alternate 模式下使用) |
135
+ | color | `"accent" | "success" | "warning" | "danger" | "info" | "muted"` | `"accent"` | 圆点颜色 |
136
+ | dot | `ReactNode` | — | 自定义圆点内容 |
137
+
138
+
139
+ ---
140
+ [← 回到索引](../llms.md)
package/docs/llms.md CHANGED
@@ -3,7 +3,7 @@
3
3
  > 拟态风格的 React 18 组件库,目标是 Electron 桌面应用。**写给 AI 编程助手**的按需文档 —— 每个组件单独一个 `.md`,避免一次性读取全部。示例源自 playground 的 demo,可直接复制运行。
4
4
 
5
5
  - **包名**: `@fangxinyan/lumina`
6
- - **版本**: `0.4.0`
6
+ - **版本**: `0.5.1`
7
7
  - **React 最低版本**: 18
8
8
  - **环境**: 带打包器的 React 工程(Vite / Next.js / Webpack / Remix / Electron + Vite 等)
9
9
  - **零运行时依赖**: 只依赖 `react` / `react-dom` (peer deps)
@@ -69,16 +69,17 @@
69
69
  - [Tag 标签](./llms/tag.md) — 标记关键词、状态或分类。
70
70
  - [Badge 徽标数](./llms/badge.md) — 右上角的小型计数或状态指示器。
71
71
  - [Avatar 头像](./llms/avatar.md) — 用图像、首字母代表用户或事物。
72
+ - [Image 图片](./llms/image.md) — 凹陷外框包裹的图片容器,带预览、错误占位。
72
73
  - [Divider 分隔符](./llms/divider.md) — 对内容进行分割。
73
74
  - [Progress 进度](./llms/progress.md) — 条形进度 Progress 与环形进度 Ring。
75
+ - [Timeline 时间线](./llms/timeline.md) — 垂直时间线,支持等待状态、自定义圆点、交替布局
74
76
  - [List 列表](./llms/list.md) — 承载一组结构化的同质化数据。
75
77
  - [Table 表格](./llms/table.md) — 结构化数据展示。
76
78
  - [Table Pro](./llms/tablepro.md) — 带工具栏 / 搜索 / 筛选 / 排序 / 多选 / 分页的全功能表格。
77
- - [Image 图片](./llms/image.md) — 凹陷外框包裹的图片容器,带预览、错误占位。
78
- - [Calendar 日历](./llms/calendar.md) — 查看与选择日期。
79
79
  - [Pagination 分页](./llms/pagination.md) — 分页控件,支持快速跳转与每页条数切换。
80
80
  - [Tabs 选项卡](./llms/tabs.md) — 同一层级的内容分组,通过标签切换。
81
81
  - [Accordion 折叠面板](./llms/accordion.md) — 纵向折叠面板。
82
+ - [Calendar 日历](./llms/calendar.md) — 查看与选择日期。
82
83
 
83
84
  ### 反馈
84
85
 
@@ -86,7 +87,7 @@
86
87
  - [Drawer 抽屉](./llms/drawer.md) — 从屏幕边缘滑出的浮层。
87
88
  - [Toast 通知](./llms/toast.md) — 全局轻量提示,4 种语义。
88
89
  - [Tooltip 文字提示](./llms/tooltip.md) — 鼠标悬浮触发的简短说明。
89
- - [Popover 气泡卡片](./llms/popover.md) — 比 Tooltip 更丰富,可承载交互内容。
90
+ - [Popover 气泡卡片](./llms/popover.md) — 比 Tooltip 更丰富,可承载交互内容。
90
91
  - [Alert 警告提示](./llms/alert.md) — 页面中嵌入的警告/提示。
91
92
  - [Empty 空状态](./llms/empty.md) — 列表、页面或容器无数据时的占位。
92
93
  - [Spinner 加载](./llms/spinner.md) — 表示任务正在进行,提示用户等待。
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fangxinyan/lumina",
3
- "version": "0.4.0",
3
+ "version": "0.5.1",
4
4
  "description": "Lumina — Neumorphic component library for Electron & React apps",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -47,11 +47,15 @@
47
47
  "react-dom": ">=18"
48
48
  },
49
49
  "devDependencies": {
50
+ "@babel/standalone": "^7.29.2",
51
+ "@types/node": "^25.6.0",
52
+ "@types/prismjs": "^1.26.6",
50
53
  "@types/react": "^18.3.3",
51
54
  "@types/react-dom": "^18.3.0",
52
55
  "@vitejs/plugin-react": "^4.3.1",
53
56
  "postcss": "^8.5.10",
54
57
  "postcss-import": "^16.1.1",
58
+ "prismjs": "^1.30.0",
55
59
  "react": "^18.3.1",
56
60
  "react-dom": "^18.3.1",
57
61
  "tsup": "^8.2.4",
@@ -1,10 +0,0 @@
1
- /* ============ Popover ============ */
2
- .popover {
3
- z-index: 1000;
4
- background: var(--bg);
5
- border-radius: var(--r-md);
6
- padding: var(--gap-3);
7
- min-width: 220px;
8
- box-shadow: var(--neu-float);
9
- animation: menuIn var(--dur) var(--ease);
10
- }